2012-03-28 6 views
0

Я попытался использовать цикл for для ввода данных, но стал слишком проблематичным. Поэтому я попытался использовать цикл while, он работает, но когда я попытался его отладить, он продолжал помещать -858993460 в каждый слот. Файл .dat находится в нужном месте и открывается.Цикл WHILE и ввод данных

#include <iostream> 
#include <fstream> 
#include <string> 
using namespace std; 

struct record 
{ 
    int item_id; 
    string item_type; 
    float item_price; 
    int num_stock; 
    string item_title; 
    string item_author; 
    int year_published; 
}; 

void read_all_records(record records[], int &valid_entries); 
int num_inventory_of_type(record records[], string type, int &valid_entries); 
const int max_array = 100; 
int main() 
{ 
    int valid_entries = 0; 
    record records[max_array]; 
    read_all_records(records, valid_entries); 

    cout << "Stock Report" << endl; 
    cout << "------------" << endl; 
    int book = num_inventory_of_type(records, "book", valid_entries); 
    cout << "Book's In Stock: " << book << endl; 
    int cd = num_inventory_of_type(records, "cd", valid_entries); 
    cout << "CD's In Stock: " << cd << endl; 
    int dvd = num_inventory_of_type(records, "dvd", valid_entries); 
    cout << "DVD's In Stock: " << dvd << endl; 

    return 0; 
} 

void read_all_records(record records[], int &valid_entries) 
{ 
    ifstream invfile; 
    invfile.open("inventory.dat"); 
    if (!invfile.is_open()) 
    { 
     cout<<"file open failed"; 
     exit(1); 
    } 
    while(invfile.good() && valid_entries < max_array) 
    { 
     invfile >> records[valid_entries].item_id >> records[valid_entries].item_type 
      >> records[valid_entries].item_price >> records[valid_entries].num_stock 
      >> records[valid_entries].item_title >> records[valid_entries].item_author 
      >> records[valid_entries].year_published; 
     if(!invfile.good()) 
      break; 
     valid_entries++; 

    } 
    invfile.close(); 

} 
int num_inventory_of_type(record records[], string type, int &valid_entries) 
{ 
    int count = 0; 
    int holder = 0; 
    for (int count = 0; count<valid_entries; count++); 
    {  
     if (records[count].item_type == type) 
     { 
      holder+=records[count].num_stock; 

     } 
    } 

    return holder; 
} 

файл .dat является

123456 
book 
69.99 
16 
Problem_Solving_With_C++ 
Walter_Savitch 
2011 
123457 
cd 
9.99 
32 
Sigh_No_More 
Mumford_and_Sons 
2010 
123458 
dvd 
17.99 
15 
Red_State 
Kevin_Smith 
2011 
123459 
cd 
9.99 
16 
The_Church_Of_Rock_And_Roll 
Foxy_Shazam 
2012 
123460 
dvd 
59.99 
10 
The_Walking_Dead_Season_1 
Robert_Kirkman 
2011 

все новые линии, без пробелов.

В основном он должен начать, запустите функцию read_all_records и поместите данные .dat в массив. Тем не менее, я положил cout << records[count].item_id; в цикл while, чтобы увидеть, действительно ли данные поступают, и я получаю -858993460 каждый раз. После этого он должен запускать следующую функцию 3 раза и возвращать сколько из каждой книги есть.

+0

'while (! Invfile.eof())' <- ну есть ваша ошибка. –

+1

Указатель StackOverflow должен дать минимальный пример - наименьшее количество кода, которое по-прежнему отображает вашу ошибку. Никто не хочет смотреть на все это. Это может помочь вам разобраться в этом. – cmo

+0

Какая ошибка Mooing Duck? @CycoMatto, прошу прощения. Я просто хотел, чтобы все поняли, в чем проблема, потому что у меня есть нулевая подсказка. – Nogg

ответ

1

Вы использовали целочисленный тип int на item_price. invfile >> records[count].item_price затем извлекает только 69 вместо 69.99, что приводит к ошибке при попытке извлечь year_published.

Вместо этого используйте float или double.

struct record 
{ 
    int item_id; 
    string item_type; 
    float item_price; 
    int num_stock; 
    string item_title; 
    string item_author; 
    int year_published; 
}; 

/* skipped identical lines */ 

while(invfile.good() && count < max_array) 
{ 
    invfile >> records[count].item_id >> records[count].item_type 
     >> records[count].item_price >> records[count].num_stock 
     >> records[count].item_title >> records[count].item_author 
     >> records[count].year_published; 
     cout << records[count].item_price << endl; 
     if(!invfile.good()) 
      break; 
    cout << records[count].item_id << endl; 
     count++; 
} 
invfile.close(); 

Обратите внимание, что у вас есть дополнительные точки с запятой в for (int count = 0; count<max_array; count++);. Наверное, вы этого не хотели, так что удалите его.

+0

Я топчу свою голову прямо сейчас, чтобы не видеть этого. О, МОЙ БОГ. Я потратил серьезно 10 часов, пытаясь решить эту проблему ... спасибо вам, много. – Nogg

+0

@Nogg: Иногда бывает неплохо печатать больше значений;) - идентификатор был действительным, 'item_type' тоже, но' item_price' был неправильным , Также активируйте предупреждения компилятора ('-Wall -Wextra' в gcc). Попробуйте реализовать 'std :: istream & operator >>', который предоставил Марсело, это сделает ваш код немного легче читать. – Zeta

+0

не могли бы вы помочь мне еще сделать еще один шаг? После этого я отредактирую свой код, не могли бы вы перечислить его и сказать, почему, когда я выводю его, выдает правильные книги, но вывод cd и dvd равен нулю. Ничто не отличается от этих трех. – Nogg

1

Это не является прямым ответом на проблему, но, возможно, он уйдет после рефакторинга:

std::istream& operator>>(std::istream& is, record& r) { 
    return is >> r.item_id >> r.item_type >> … >> r.year_published; 
} 

int main() { 
    if (std::ifstream invfile("inventory.dat")) { 
     std::vector<record> records((std::istream_iterator<record>(invfile)), 
            std::istream_iterator<record>()); 

     num_inventory_of_type(records, "dvd"); 
     num_inventory_of_type(records, "cd"); 
     num_inventory_of_type(records, "book"); 
    } 
} 

Если вы все еще хотите, чтобы распечатать каждую запись, как вы читаете это, то код может быть перегруппированы следующим образом:

 std::vector<record> records; 
     for (std::istream_iterator<record> i(invfile); 
      i != std::istream_iterator<record>(); ++i) 
     { 
      records.push_back(*i); 
      std::cout << i->item_id << "\n"; 
     } 
+0

Я просто хочу знать, почему мой способ не работает? – Nogg

+0

После записи последней записи '! Invfile.eof()' преуспевает, поэтому вы читаете еще одну «запись» после последней действительной записи. Теперь это объясняет мусор, который вы видите, но только на последней записи, тогда как формулировка вашего вопроса подразумевает, что у каждой записи есть проблема, которая не имеет большого смысла. В любом случае, вы действительно не должны писать код таким образом. Вышеприведенный ответ короче, чище и, что важно, не уязвим для ошибок, которые могут возникнуть отдельно от вашего кода. Не будьте так быстро, чтобы уволить помощь только потому, что она не предлагается на ваших условиях. –

+0

ОК, он, наконец, щелкнул (после прочтения других ответов). Вы устанавливаете 'record [0]', а затем печатаете 'record [1]', который, очевидно, еще ничего не имеет в нем. Это не отрицает ошибку '! Invfile.eof()', заметьте. –

0

Необходимо изменить int item_price; для float so -> float item_price;

и, как уже упоминалось выше, вам необходимо поменять граф ++; и cout < < записей [count] .item_id.

После этих двух изменений он будет работать должным образом.

struct record 
{ 
    int item_id; 
    string item_type; 
    float item_price; // <--- Needs to be a float 
    int num_stock; 
    string item_title; 
    string item_author; 
    int year_published; 
}; 


// This order is required because you are storing in the current 'count' record and then you need to print it. Then increment the count to store the next record 
cout << records[count].item_id; 
count++; 
Смежные вопросы