Чтение из текстового файла с помощью 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
, Но лучшим решением было бы работать с указателями на структуры, а не на сами структуры.