从未知大小列表中填充C中的锯齿状char数组

时间:2016-06-15 18:19:09

标签: c arrays string

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编程对我来说是新的,似乎需要一种不同的思维方式,我仍然在努力。

我读过这么多书和帮助问题,但我似乎是在圈子里。

如果我的方法有误,过度观点可能会有所帮助。

1 个答案:

答案 0 :(得分:1)

这显示了如何构建一个播放列表数组,每个播放列表包含一个歌曲标题数组。使用全局数组并不是一个好习惯,但为了简单起见,我已经这样做了。

每个播放列表都有一系列歌曲标题指针。当该数组已满时,它将被扩展。在实践中,SONGS的值越大,该程序就越有效。

我让你从文件中提取数据。由于token指向的标题会被覆盖,我在MSVC(调用strdup)中使用_strdupmalloc来制作每个标题的副本。在程序结束时,您应该迭代数组,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