C程序。 将编译为Linux 32位和Windows 32位。
gcc (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4
i686-w64-mingw32-gcc (GCC) 4.8.2
目标:
将包含歌曲列表的单个char数组分解为多维char数组。 我会走路'这个数组与另一个列表进行比较然后做“工作”。在它上面,如删除歌曲或转换歌曲。
缓冲区和歌曲名称大小未知。
缓冲区包含“[playlist1] \ n12345 \ n54321 \ n [playlist2] \ n6789 \ n9876 \ n [playlist3] \ n更长的歌曲名称\ n”
需要一个包含播放列表#和歌曲名称的数组。
112345
154321
26789
29876
3个更长的歌曲名称
array [0] [0]应该包含1(int 48)
array [0] [2]应该包含2(int 50) ...
工作:
我已经计算了'\ n'的数量来获得数组总行数(暂时忽略“[playlist1]”)
int array_length_all_songs = 0;
int index;
for (index = 0; index<plLength; index++)
{
if (plBuffer[index] == '\n')
{
array_length_all_songs++;
}
}
创建了一个char类型数组
char **array_playlist = calloc(array_length_all_songs, sizeof(char *));
填充数组
char *token; /* "\x0a" == "\n" */
char pl_num; /* remember a char is an int */
int array_length_working;
int song_name_length;
token = strtok(plBuffer,"\x0a");
while(token != NULL)
/* set playlist number */
if(strncmp(token,"[Playlist",9) == 0)
{
//printf("token: %s\n",token);
pl_num = (unsigned char)token[9];
//printf("pl: %c\n",pl_num);
}
else
{
array_length_working++;
switch (pl_num)
{
case '1':
if(strncmp(token,"[Playlist",9) != 0)
{
song_name_length = strlen(token);
array_playlist[array_length_working] = calloc(song_name_length, sizeof(char));
strcpy(&array_playlist[array_length_working], token);
}
break;
case '2':
...
由于我正在努力解决的指针和类型转换,此代码无效。
strcpy(&array_playlist[array_length_working], token);
我决定使用这种创建数组的方法,即使我必须走一次缓冲区以获得大小。 我相信这种方法被称为 Iliffe vector 。
问题:
对于内存受限的计算机,我是否接近这个错误或效率低下?
如果不是......
我需要弄清楚如何将$ token复制到数组$ array [123] [0] 因为令牌是一个字符数组(int),我必须复制每个字符,还是可以将整个'字符串'复制到新位置?
我无法动态创建变量$ song1所以我无法将歌曲名称的指针放入数组中。因此,我必须将所有单个char复制到数组中。 $阵列[123] [N ++]。正确?
我已经习惯了很多年的编程,但c编程对我来说是新的,似乎需要一种不同的思维方式,我仍然在努力。
我读过这么多书和帮助问题,但我似乎是在圈子里。
如果我的方法有误,过度观点可能会有所帮助。
答案 0 :(得分:1)
这显示了如何构建一个播放列表数组,每个播放列表包含一个歌曲标题数组。使用全局数组并不是一个好习惯,但为了简单起见,我已经这样做了。
每个播放列表都有一系列歌曲标题指针。当该数组已满时,它将被扩展。在实践中,SONGS
的值越大,该程序就越有效。
我让你从文件中提取数据。由于token
指向的标题会被覆盖,我在MSVC(调用strdup
)中使用_strdup
或malloc
来制作每个标题的副本。在程序结束时,您应该迭代数组,free
每个标题的内存,然后free
每个指针数组。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LISTS 4 // number of play lists
#define SONGS 3 // incremental number of songs per list
typedef struct {
int numsongs; // number of songs in list
int maxsongs; // maximum possible songs in list
char **song; // base of array of pointers
} list_t;
list_t lib[LISTS] = { {0} };
void addsong(int listnum, char *title)
{
list_t *ptr;
char **arr;
if (listnum < 1 || listnum > LISTS) {
exit(1); // or other error checking
}
ptr = &lib[listnum-1]; // for convenience, and arrays are 0-based
if (ptr->numsongs >= ptr->maxsongs) {
// extend the song titles array
arr = realloc(ptr->song, (ptr->maxsongs + SONGS) * sizeof(char*));
if(arr == NULL) {
exit(1); // or other error checking
}
ptr->song = arr; // new bigger array
ptr->maxsongs += SONGS; // more capacity
}
// save a pointer to a copy of the song title
ptr->song[ ptr->numsongs ] = _strdup(title);
ptr->numsongs++;
}
int main(void)
{
int i, j;
// add songs to playlists in random order
addsong(2, "Song two/one");
addsong(1, "Song one/one");
addsong(4, "Song four/one");
addsong(2, "Song two/two");
addsong(1, "Song one/two");
addsong(2, "Song two/three");
addsong(2, "Song two/four");
addsong(2, "Song two/five");
addsong(1, "Song one/three");
// show what we've got
for(i=0; i<LISTS; i++) {
printf("Playlist %d\n", i + 1);
for(j=0; j<lib[i].numsongs; j++) {
printf(" %s\n", lib[i].song[j]);
}
}
return 0;
}
节目输出:
Playlist 1
Song one/one
Song one/two
Song one/three
Playlist 2
Song two/one
Song two/two
Song two/three
Song two/four
Song two/five
Playlist 3
Playlist 4
Song four/one