2017-09-28 320 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; 
}