从文件扫描到Mallocated Structs数组? (C)

时间:2014-11-14 13:49:27

标签: c

我在将文件中的数据读入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

阅读辣椒和美国墨西哥的作品很好。但是,当我尝试打印辣椒的价格或评级时,价格始终打印0.0,评级总是超过100万。我在这做错了什么?我猜测它必须是分配内存的东西,或者是我想读它的方式。

2 个答案:

答案 0 :(得分: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);

答案 1 :(得分: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代码中的错误部分。功能