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

时间:2017-09-28 19:24:37

标签: c arrays gcc struct allocation

我试图将大型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内部分配内存有问题,但我确信在哪里。 在此之后,我在fgets()循环中使用while来读取文件,并在它通过每一行时将值存储在struct的成员中,并且当它到达时我还重新分配了内存MAX_ROW

2 个答案:

答案 0 :(得分:1)

这是一个示例,说明如何将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;
}

答案 1 :(得分:0)

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

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

解决方案可能是分配结构,然后为结构中的每个指针分配其他内存。但是,如果您知道结构中每个字符串需要多少空间,则只需用char *variable替换每个char variable[SIZE]。这样sizeof(struct name)将分配正确的空间,您不需要在之后分配每个字符串。