2014-11-14 27 views
0

我有一些麻煩閱讀數據從一個文件中的數組內存分配的結構在c。我的相關代碼如下:從文件掃描到Mallocated Structs數組中? (c)

//Struct that holds the restaurant information 
typedef struct 
{ 
    char *name; 
    char *food; 
    double *price; 
    int *rating; 
}RESTAURANT; 

//Function to get all the reviews from the file 
void reviews() 
{ 
    int numReviews, i; 
    char tempBuffer[BUFFER_SIZE]; //hold the user input 

    RESTAURANT *reviews; //create an array of structs 

    FILE *inputFile; //file pointer 

    inputFile = fopen(INPUT_FILE_NAME, "r"); //open the input file 

    //Get the number of reviews from the top of the file 
    fgets(tempBuffer, BUFFER_SIZE, inputFile); 
    sscanf(tempBuffer, "%d", &numReviews); 

    //Allocate enough space in the struct array for the number of reviews 
    reviews = malloc(sizeof(*reviews)*numReviews); 

    //Loop to allocate memory for each field in each struct 
    for(i = 0; i < numReviews; i++) 
    { 
     reviews[i].name = malloc(sizeof(char *)); 
     reviews[i].food = malloc(sizeof(char *)); 
     reviews[i].price = malloc(sizeof(double *)); 
     reviews[i].rating = malloc(sizeof(int *)); 
    } 

    //Loop to get each field for each struct from the file 
    //And store it in the struct array at the correct struct 
    for(i = 0; i < numReviews; i++) 
    { 
     fscanf(inputFile, "%s", reviews[i].name); 
     fscanf(inputFile, "%s", reviews[i].food); 
     fscanf(inputFile, "%lf", reviews[i].price); 
     fscanf(inputFile, "%d", reviews[i].rating); 
    } 

而在reviews.txt該文件是:

4 
Chili's 
AmericanizedMexican 
10.95 
3 
BurgerKing 
American 
4.50 
2 
IHOP 
American 
9.50 
1 
OliveGarden 
AmericanizedItalian 
11.00 
4 

在讀池莉和AmericanizedMexican工作正常。但是,當我嘗試打印辣椒的價格或評級時,價格總是打印0.0,評級總是超過100萬。我在這裏做錯了什麼?我猜它必須是一些與內存或用的東西,我的意思的方式來讀取它分配。

+0

兩件事情:第一,你寫在寫實際的字符串之前字符串的大小?因爲字符串大小可變,所以它看起來像。其次,你可能想使用fread,fwrite,fopen和fclose。閱讀手冊頁。 – Gophyr 2014-11-14 14:22:43

+0

@Gophyr:OP在未顯示的代碼中使用'fopen',也可能使用'fclose'。 「fread」如何在這裏幫助?數據是ASCII數據,可以用'fgets'和'fscanf'讀取。 'fread'用於已知字節大小的數據。在代碼中,什麼也沒有寫;它是關於從文件中讀取的。 – 2014-11-14 14:26:27

+0

'fread'和'fwrite'允許您控制讀取/寫入元素的大小和數量。 – Gophyr 2014-11-14 15:36:44

回答

2

我不知道,但通過指針存儲標量值,如價格和評級作爲分配數據似乎很奇怪。你可以這樣做,但是會增加很多分配開銷。記住,你必須free你已經分配的一切。

除此之外,你得到了分配錯誤:

reviews[i].name = malloc(sizeof(char *)); 
    reviews[i].food = malloc(sizeof(char *)); 
    reviews[i].price = malloc(sizeof(double *)); 
    reviews[i].rating = malloc(sizeof(int *)); 

您分配內存來保存的東西指針的大小。你必須分配可以容納指向的東西的內存。一個有用的分配模式是:

x = malloc(sizeof(*x)); 

爲單值和

x = malloc(count * sizeof(*x)); 

爲長度count的陣列。你已經這樣做了reviews。你的字符串,即char數組,應該是這樣的數組。所以你應該分配:

reviews[i].name = malloc(MAX_LEN * sizeof(char)); 
    reviews[i].food = malloc(MAX_LEN * sizeof(char)); 
    reviews[i].price = malloc(sizeof(double)); 
    reviews[i].rating = malloc(sizeof(int)); 

其中MAX_LEN是一個或多或少的任意限制,你必須設置和強制執行。 (例如,您應確保fscanf絕不會向緩衝區寫入超過'MAX_LEN'個字符;其中包括尾部空字符。)

您對標量值的處理很尷尬。我的結構改變爲

typedef struct { 
    char *name; 
    char *food; 
    double price;  // Store values, not pointers 
    int rating;  // Same here 
} RESTAURANT; 

扔出去的分配和直接掃描到這些領域,使用地址操作&獲取一個指針:

fscanf(inputFile, "%lf", &reviews[i].price); 
    fscanf(inputFile, "%d", &reviews[i].rating); 
+0

謝謝,你解決了我的問題。我曾嘗試將它們存儲爲沒有分配的值,但我忘記了,但在掃描過程中,我很傻。再次感謝! – bibzuda7 2014-11-14 14:11:42

1

你的問題是

for(i = 0; i < numReviews; i++) 
    { 
     reviews[i].name = malloc(sizeof(char *)); 
     reviews[i].food = malloc(sizeof(char *)); 
     reviews[i].price = malloc(sizeof(double *)); 
     reviews[i].rating = malloc(sizeof(int *)); 
    } 

在這裏,沒有足夠的內存分配。

做到這一點

for(i = 0; i < numReviews; i++) 
    { 
     reviews[i].name = malloc(128 *sizeof(char)); 
     reviews[i].food = malloc(128 *sizeof(char)); 
     reviews[i].price = malloc(sizeof(double)); 
     reviews[i].rating = malloc(sizeof(int)); 
    } 

編輯:

值128僅用於演示的目的,只是想指出在OP的代碼錯誤的部分。

+0

如果名字大於127,該怎麼辦? – nouney 2014-11-14 13:59:26

+0

爲什麼128?只是因爲? – 2014-11-14 13:59:41

+0

@nouney&@ Filipe嗯,這只是一個提示。 – 2014-11-14 14:00:45