2015-02-06 3 views
-1

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

например, у меня есть файл вроде этого.

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; 
} 
+0

В дополнение к '' '' '' 'и' double', предложите: вместо сравнения 'fscanf (...)! = EOF)', используйте 'fscanf (...) == 4) '. Это приведет к завершению цикла по проблеме сканирования, а не к застреванию в бесконечном цикле. IOW, используйте данные, когда код получает _all_ свои входы. – chux

ответ

1

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

Пункт 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: В входном файле, вход в каждой линии

Smith 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; 
} 
+0

Странно, он все еще не распечатывает имя клиента. – ln206

+0

@ ln206 Проверьте мой ответ. –

+0

Спасибо, что объяснил, что я сделал не так, я был занят целый день до сих пор. Очень хорошо объяснил, спасибо! – ln206

0

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

+0

Это означает, что я должен сделать больше переменных temp и затем инициализировать структуру оттуда? Благодарю. – ln206

+0

Я бы сказал наоборот. Избавиться от 'c' и работать непосредственно с элементами массива. Или сделайте 'c' типа' customer * ', присвойте' & cus_array [customerCounter] 'ему, а затем прочитайте свои данные в' c-> whatever'. –

Смежные вопросы