使用 realloc 动态增加 C 中的数组大小

Dynamically increase array size in C using realloc

我正在尝试将文件的元素保存到结构数组中。

我想动态增加数组中分配的内存以适应文件中的行(结构)总数。

.txt 文件如下所示:

R&B;6jvvpPJQJy5rMOEkLlADl6;Trey Songz
R&B;6p8JTP4A9NZHtxRVhkEo6s;T-Pain
R&B;3SwhPTNNU5hpF33bbCsji6;BJ The Chicago Kid
R&B;5yvhdo8FXbBsIllxv2Rr94;SZA
R&B;5Yq38evNk28qlTVHHtwBhT;James Blake
R&B;5yamjs92dcayRVlNuY116G;H.E.R.
R&B;4FjcZsKyGhhZnuYq0nzXpZ;T-Pain
R&B;22jnEneSABg4vRCR1vow7F;Daniel Caesar
R&B;57qiTKh8bVX0VtfUNTQqhw;The Weeknd

这是我目前的代码。 (songFilesongsListgenresList 做同样的事情,但目前没有实现)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


typedef struct genresFile{
    char* genre;
    char* idSong;
    char* artist;
} genresFile;

typedef struct songsFile{
    char* idSong;
    int popularity;
    char* mode;
} songsFile;


int main(int argc, char *argv[])
{
    FILE* songs = fopen("songs.txt", "r");
    FILE* genres = fopen("genres.txt", "r");
    
    genresFile* genresList = NULL;
    //songsFile* songsList = NULL;

    char *buf = malloc(256);
    char *tmp;

    int i = 0;
    while (fgets(buf, 255, genres)){      
        genresList = realloc(genresList, (i+1)*sizeof(genresFile));
        if ((strlen(buf)>0) && (buf[strlen (buf) - 1] == '\n'))
            buf[strlen (buf) - 1] = '[=11=]';       
        genresFile object;
        tmp = strtok(buf, ";");
        object.genre = tmp;

        tmp = strtok(NULL, ";");
        object.idSong = tmp;

        tmp = strtok(NULL, ";");
        object.artist = tmp;

        genresList[i] = object;
        i++;
    }
    
    printf("%s, %s, %s\n",genresList[3].genre, genresList[3].idSong, genresList[3].artist);

    
    free(genresList);
    //free(songsList);
    fclose(songs);
    fclose(genres);
    return 0;
}

这是我最后从打印中得到的输出:

Soul, qWZdkBl4UVPj9lK6HuuFM, r Thomas & The Volcanos

这是 .txt 文件的最后一行,艺术家的名字开头少了一个字母。

这将保存在数组的每个元素中。请帮忙:D

分配指针并不意味着复制字符串。

缓冲区buf在下面的行中被覆盖,因此指针指向的内容也发生了变化。

为避免这种情况,您应该复制字符串而不是仅仅分配指针。

可以这样做:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


typedef struct genresFile{
    char* genre;
    char* idSong;
    char* artist;
} genresFile;

typedef struct songsFile{
    char* idSong;
    int popularity;
    char* mode;
} songsFile;

char* copy_string(const char* str) {
    char* copy = malloc(strlen(str) + 1); /* +1 for terminating null-character */
    if (copy != NULL) strcpy(copy, str);
    return copy;
}

int main(int argc, char *argv[])
{
    FILE* songs = fopen("songs.txt", "r");
    FILE* genres = fopen("genres.txt", "r");
    
    genresFile* genresList = NULL;
    //songsFile* songsList = NULL;

    char *buf = malloc(256);
    char *tmp;

    int i = 0;
    while (fgets(buf, 255, genres)){      
        genresList = realloc(genresList, (i+1)*sizeof(genresFile));
        if ((strlen(buf)>0) && (buf[strlen (buf) - 1] == '\n'))
            buf[strlen (buf) - 1] = '[=10=]';       
        genresFile object;
        tmp = strtok(buf, ";");
        object.genre = copy_string(tmp);

        tmp = strtok(NULL, ";");
        object.idSong = copy_string(tmp);

        tmp = strtok(NULL, ";");
        object.artist = copy_string(tmp);

        genresList[i] = object;
        i++;
    }
    
    printf("%s, %s, %s\n",genresList[3].genre, genresList[3].idSong, genresList[3].artist);

    
    free(genresList);
    //free(songsList);
    fclose(songs);
    fclose(genres);
    return 0;
}

如果您的(目标)环境支持,您可以使用 strdup() 代替 copy_string()