将.csv文件存储在c中动态分配的结构数组中

Storing .csv file in dynamically allocated array of struct in c

我正在尝试将大型 csv 文件存储到一个动态分配的 C 语言结构数组中,但我不知道为什么,但我在文件中的 5 行后一直获取段默认值。我正在使用 gcc 编译和 cat [NameOfFile].csv|... 将 csv 文件包含到标准输入中。所以我的 struct 是:

typedef struct{
    int num_critic_for_reviews;
    int duration;
    int director_facebook_likes; 
    int actor_3_facebook_likes; 
    int actor_1_facebook_likes; 
    int gross; 
    int num_voted_users; 
    int cast_total_facebook_likes;
    int facenumber_in_poster;
    int budget; 
    int title_year; 
    int actor_2_facebook_likes; 
    int imdb_score; 
    int aspect_ratio; 
    int movie_facebook_likes;    
    int num_user_for_reviews;
    char* color;
    char* director_name;
    char* actor_2_name;  
    char* genres; 
    char* actor_1_name; 
    char* movie_title;  
    char* actor_3_name; 
    char* plot_keywords; 
    char* movie_imdb_link;
    char* language; 
    char* country; 
    char* content_rating;        
}csvfile;
typedef csvfile CSVFILE;

我声明:

CSVFILE data[MAX_ROW]; //MAX_ROW = 1000;

并分配内存里面的数据:

CSVFILE* data = (CSVFILE*) malloc((MAX_ROW * sizeof(csvfile)));

我认为我在 data 中分配内存的方式有问题,但我很确定在哪里。 在此之后,我在 while 循环中使用 fgets() 来读取文件并将值存储在 struct 的成员中,当它遍历每一行时,当它到达时我也重新分配了内存MAX_ROW

我认为问题是你没有在你的结构中分配 char *s。

当你有一个带有指针的结构时,一个简单的 malloc(sizeof(struct name)); 将只分配每个变量所需的 space,在指针的情况下只是 space 到存储指针地址。这意味着您的 char * 指针将指向内存中未分配的某个位置。

一个解决方案可能是分配结构,然后为结构中的每个指针分配其他内存。但是,如果您知道 space 需要您的结构中的每个字符串,您可以简单地将每个 char *variable 替换为 char variable[SIZE]。这样 sizeof(struct name) 将分配正确的 space 并且您不需要分配之后的每个字符串。

下面是一个示例,说明如何将 CSV 文件中的所有记录读取到动态分配的结构中:

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

#define LINE_MAX_LEN            (1024 * 4)   /* 4 KBytes */

struct record_s
{
    int num_critic_for_reviews;
    int duration;
    int director_facebook_likes;
    int actor_3_facebook_likes;
    int actor_1_facebook_likes;
    int gross;
    int num_voted_users;
    int cast_total_facebook_likes;
    int facenumber_in_poster;
    int budget;
    int title_year;
    int actor_2_facebook_likes;
    int imdb_score;
    int aspect_ratio;
    int movie_facebook_likes;
    int num_user_for_reviews;
    char* color;
    char* director_name;
    char* actor_2_name;
    char* genres;
    char* actor_1_name;
    char* movie_title;
    char* actor_3_name;
    char* plot_keywords;
    char* movie_imdb_link;
    char* language;
    char* country;
    char* content_rating;
};

typedef struct record_s record_t;


char ** strsplit( const char * src, const char * delim )
{
    char * pbuf = NULL;
    char * ptok = NULL;
    int count = 0;
    int srclen = 0;
    char ** pparr = NULL;

    srclen = strlen( src );

    pbuf = (char*) malloc( srclen + 1 );

    if( !pbuf )
        return NULL;

    strcpy( pbuf, src );

    ptok = strtok( pbuf, delim );

    while( ptok )
    {
        pparr = (char**) realloc( pparr, (count+1) * sizeof(char*) );
        *(pparr + count) = strdup(ptok);

        count++;
        ptok = strtok( NULL, delim );
    }

    pparr = (char**) realloc( pparr, (count+1) * sizeof(char*) );
    *(pparr + count) = NULL;

    free(pbuf);

    return pparr;
}


void strsplitfree( char ** strlist )
{
    int i = 0;

    while( strlist[i])
        free( strlist[i++] );

    free( strlist );
}


record_t * parse_record( char * line )
{
    char ** pp = NULL;
    record_t * rec = NULL;

    pp = strsplit( line, ";" );

    rec = (record_t*) calloc( 1, sizeof(record_t) );

    rec->num_critic_for_reviews = atoi(pp[0]);
    rec->duration = atoi(pp[1]);
    rec->director_facebook_likes = atoi(pp[2]);
    rec->actor_3_facebook_likes = atoi(pp[3]);
    rec->actor_1_facebook_likes = atoi(pp[4]);
    rec->gross = atoi(pp[5]);
    rec->num_voted_users = atoi(pp[6]);
    rec->cast_total_facebook_likes = atoi(pp[7]);
    rec->facenumber_in_poster = atoi(pp[8]);
    rec->budget = atoi(pp[9]);
    rec->title_year = atoi(pp[10]);
    rec->actor_2_facebook_likes = atoi(pp[11]);
    rec->imdb_score = atoi(pp[12]);
    rec->aspect_ratio = atoi(pp[13]);
    rec->movie_facebook_likes = atoi(pp[14]);
    rec->num_user_for_reviews = atoi(pp[15]);
    rec->color = strdup(pp[16]);
    rec->director_name = strdup(pp[17]);
    rec->actor_2_name = strdup(pp[18]);
    rec->genres = strdup(pp[19]);
    rec->actor_1_name = strdup(pp[20]);
    rec->movie_title = strdup(pp[21]);
    rec->actor_3_name = strdup(pp[22]);
    rec->plot_keywords = strdup(pp[23]);
    rec->movie_imdb_link = strdup(pp[24]);
    rec->language = strdup(pp[25]);
    rec->country = strdup(pp[26]);
    rec->content_rating = strdup(pp[27]);

    strsplitfree( pp );

    return rec;
}


void destroy_record( record_t * rec )
{
    free(rec->color);
    free(rec->director_name);
    free(rec->actor_2_name);
    free(rec->genres);
    free(rec->actor_1_name);
    free(rec->movie_title);
    free(rec->actor_3_name);
    free(rec->plot_keywords);
    free(rec->movie_imdb_link);
    free(rec->language);
    free(rec->country);
    free(rec->content_rating);
    free(rec);
}


void show_record( record_t * rec )
{
    printf( "[ RECORD ]\n" );
    printf( "   num_critic_for_reviews: %d\n", rec->num_critic_for_reviews );
    printf( "   duration: %d\n", rec->duration );
    printf( "   director_facebook_likes: %d\n", rec->director_facebook_likes );
    printf( "   actor_3_facebook_likes: %d\n", rec->actor_3_facebook_likes );
    printf( "   actor_1_facebook_likes: %d\n", rec->actor_1_facebook_likes );
    printf( "   gross: %d\n", rec->gross );
    printf( "   num_voted_users: %d\n", rec->num_voted_users );
    printf( "   cast_total_facebook_likes: %d\n", rec->cast_total_facebook_likes );
    printf( "   facenumber_in_poster: %d\n", rec->facenumber_in_poster );
    printf( "   budget: %d\n", rec->budget );
    printf( "   title_year: %d\n", rec->title_year );
    printf( "   actor_2_facebook_likes: %d\n", rec->actor_2_facebook_likes );
    printf( "   imdb_score: %d\n", rec->imdb_score );
    printf( "   aspect_ratio: %d\n", rec->aspect_ratio );
    printf( "   movie_facebook_likes: %d\n", rec->movie_facebook_likes );
    printf( "   num_user_for_reviews: %d\n", rec->num_user_for_reviews );
    printf( "   color: %s\n", rec->color );
    printf( "   director_name: %s\n", rec->director_name );
    printf( "   actor_2_name: %s\n", rec->actor_2_name );
    printf( "   genres: %s\n", rec->genres );
    printf( "   actor_1_name: %s\n", rec->actor_1_name );
    printf( "   movie_title: %s\n", rec->movie_title );
    printf( "   actor_3_name: %s\n", rec->actor_3_name );
    printf( "   plot_keywords: %s\n", rec->plot_keywords );
    printf( "   movie_imdb_link: %s\n", rec->movie_imdb_link );
    printf( "   language: %s\n", rec->language );
    printf( "   country: %s\n", rec->country );
    printf( "   content_rating: %s\n", rec->content_rating );
    printf( "\n" );
}


int main( int argc, char * argv[] )
{
    char line[ LINE_MAX_LEN + 1 ];
    record_t * r = NULL;
    FILE * fp = NULL;

    fp = fopen( argv[1], "r" );

    while( fgets( line, LINE_MAX_LEN, fp ) )
    {
        r = parse_record( line );
        show_record( r );
        destroy_record( r );
    }

    fclose(fp);

    return 0;
}