2017-09-28 274 views
1

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

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时我也重新分配了内存。

+0

你为一个数组和指针使用相同的名称? –

+0

你是否为struct中的所有指针分配了空间,比如'color','director_name'等。 – Barmar

回答

0

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

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

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

0

这里有一个例子说明如何阅读从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; 
}