Чтение из текстового файла с помощью fscanf()

У меня проблемы с выяснением, что пошло не так в моем коде. Я думаю, что мой цикл while не читал файл правильно, я пытался распечатать имя клиента, но ничего не показывалось.

например, у меня есть такой файл.

Smith 3 Sweater $22.50
Reich 3 Umbrella $12.50
Smith 1 Microwave $230.00
Lazlo 1 Mirror $60.00
Flintstone 5 Plate $10.00
Lazlo 1 Fridge $1200.00
Stevenson 2 Chair $350.00
Smith 10 Candle $3.50
Stevenson 1 Table $500.00
Flintstone 5 Bowl $7.00
Stevenson 2 Clock $30.00
Lazlo 3 Vase $40.00
Stevenson 1 Couch $800.00

Вот мой код:

#include <stdio.h>
#include <string.h>

struct orders_tag {
    int number_of_orders;
    char item_name[20];
    double price;
};

typedef struct orders_tag order;

struct customer_tag {
    char name[30];
    order total_order[100];
};

typedef struct customer_tag customer;

int main(void) {
    FILE *infile;
    customer cus_array[20];
    customer c;
    int customerCounter = 0;

    setvbuf(stdout, NULL, _IONBF, 0);

    infile = fopen("input.txt", "r");

    if (infile == NULL) {
        printf("Couldn't open the fire.");
        return 1;
    }

    while (fscanf(infile, "%s %d %s %lf", c.name,  c.total_order[customerCounter].number_of_orders
        , c.total_order[customerCounter].item_name,  c.total_order[customerCounter].price) != EOF) {
        cus_array[customerCounter] = c;
        customerCounter++;
    }

    int j;
    for(j = 0; j < customerCounter; j++) {
        printf("%s", cus_array[j].name);
    }
    return 0;
}

2 ответа

Решение

У вас много проблем в вашем коде.

Пункт 1: Вы должны предоставить адрес [указатель] fscanf() хранить значение. + Изменить

while (fscanf(infile, "%s %d %s %lf", c.name,  c.total_order[customerCounter].number_of_orders
    , c.total_order[customerCounter].item_name,  c.total_order[customerCounter].price) != EOF) {

в

while (fscanf(infile, "%s %d %s %lf", c.name,  &c.total_order[customerCounter].number_of_orders
    , c.total_order[customerCounter].item_name,  &c.total_order[customerCounter].price) != EOF) {

Точка 2: в вашем входном файле, ввод в каждой строке

Смит 3 свитера 22,50 $

Итак, вы должны изменить свой fscanf() отформатировать в "%s %d %s $%lf" чтобы соответствовать входу. Поэтому всегда желательно проверять значение повторного запуска fscanf() и семья, чтобы обеспечить надлежащее сканирование всех ценностей.

Пункт 3: customerCounter неверное использование переменных.

Пункт 4: согласно вашему входному файлу, total_order не должен быть массивом.

Проверьте код ниже. Оно работает.

#include <stdio.h>
#include <string.h>

struct orders_tag {
        int number_of_orders;
        char item_name[20];
        double price;
};

typedef struct orders_tag order;

struct customer_tag {
        char name[30];
        order total_order;   //array not required
};

typedef struct customer_tag customer;

int main(void) {
        FILE *infile;
        customer cus_array[20];
        customer c;
        int customerCounter = 0;

        setvbuf(stdout, NULL, _IONBF, 0);

        infile = fopen("input.txt", "r");

        if (infile == NULL) {
                printf("Couldn't open the fire.");
                return 1;
        }

        while (fscanf(infile, "%s %d %s $%lf", c.name,  &c.total_order.number_of_orders
                                , c.total_order.item_name,  &c.total_order.price) != EOF) {//notice the changes here
                cus_array[customerCounter] = c;
                customerCounter++;
                if (customerCounter == 20) break; // memory allocated for only 20 elements
        }

        int j;
        for(j = 0; j < customerCounter ; j++) {
                printf("Customer :%10s, Number of order : %2d, Item : %10s, Price : $%f\n",
                        cus_array[j].name, cus_array[j].total_order.number_of_orders,cus_array[j].total_order.item_name, cus_array[j].total_order.price);
        }
        return 0;
}

В дополнение к другому ответу, строка cus_array[customerCounter] = c; не буду делать то, что вы намерены. Назначение является оператором поверхностного копирования, поэтому поля массива не будут скопированы правильно. Вместо этого вы должны скопировать поля явно, используя strcpy и / или memcpy, Но лучшим решением было бы работать с указателями на структуры, а не на сами структуры.

Другие вопросы по тегам