2012-03-28 15 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

あなたはitem_priceに整数型intを使用。 invfile >> records[count].item_price69.99の代わりに69を抽出するだけで、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:それ以上の値を印刷するのは良い考えです;) - idは有効で、 'item_type'も' item_price'が間違っていました。また、コンパイラの警告を有効にしてください(gccの '-Wall -Wextra')。 Marceloから提供された 'std :: istream&operator >>'を実装しようとすると、コードを少し読みやすくなります。 – Zeta

+0

もう一度手伝ってもらえますか?私はこの後に私のコードを編集します、あなたはそれを越えて、なぜ私はそれが正しい本を出力する出力を教えてくださいしかし、ゼロとのCDとDVDの出力。 3人の間で何も違いはありません。 – 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()'が成功するので、最後の有効なレコードの後に​​もう1つの "レコード"を読み込みます。さて、これはあなたが見ているごみを説明しますが、最後のレコードだけですが、あなたの質問の文言はすべてのレコードに問題があることを意味しますが、これはあまり意味がありません。いずれにせよ、あなたは本当にそのようにコードを書くべきではありません。上記の答えは、より短く、よりクリーンで、重要なことに、あなたのコードのようなオフ・バイ・ワンのエラーに脆弱ではありません。あなたの言葉では提供されていないので、ただちにヘルプを却下しないでください。 –

+0

OK、最後に(他の回答を読んだ後で)クリックしました。あなたは 'record [0]'を設定していて、 'record [1]'を出力しています。これは明らかにまだ何も入っていません。これは '!invfile.eof()'バグを否定するものではありません。 –

0

int item_priceを変更する必要があります。 floatにする - > float item_price;

上記のとおり、カウント++をスワップする必要があります。 cout < <レコード[count] .item_id行。

この2つの変更の後、正常に動作します。

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