看板 C_and_CPP 關於我們 聯絡資訊
開發平台(Platform): VC++ 額外使用到的函數庫: 問題(Question): 關於ifstream 的eof()與getline()兩個函式有一些問題 這兩個函式都是照手上的書的寫法來寫的 但是卻發生了很奇怪的錯誤 餵入的資料(Input): Inventory of "a" restaurant. Inventory: c 5 20 a 10 100 b 20 20 預期的正確結果(Expected Output): dq_inventory[0]{m_itemName="c",m_itemPrice=5,m_itemAmount=20} dq_inventory[1]{m_itemName="a",m_itemPrice=10,m_itemAmount=100} dq_inventory[2]{m_itemName="b",m_itemPrice=20,m_itemAmount=20} 錯誤結果(Wrong Output): dq_inventory[0]{m_itemName="c",m_itemPrice=5,m_itemAmount=20} dq_inventory[1]{m_itemName="a",m_itemPrice=10,m_itemAmount=100} dq_inventory[2]{m_itemName="b",m_itemPrice=20,m_itemAmount=20} dq_inventory[3]{m_itemName="b",m_itemPrice=20,m_itemAmount=20} (也就是說本來應該讀到結尾也就是"b"那行結束之後跳出迴圈 可是他卻又多跑了一次迴圈) 另外junk也讀到了一堆亂七八糟的東西 點開看只有第一個是'\0' 其他都是'?' 程式碼(Code):(請善用置底文網頁, 記得排版) Cinventory inventory; //Cinventory class物件宣告 deque<Cinventory> dq_inventory; //double-ended queue宣告 string itemName; int itemPrice,itemNumber; char junk[1000]; ifstream fileInput("inventory.txt",ios::in); getline(junk,1000,'\n'); //將開頭兩行讀掉,為了不跟需要的資料搞混 getline(junk,1000,'\n'); //手上的書告訴我可以讀取999個字元到junk //,或者是讀到\n就結束 while(!fileInput.eof()) //判別是否讀到檔案的尾端 { fileInput >> itemName; fileInput >> itemPrice; fileInput >> itemNumber; inventory.setInventory(itemName //之前忘記打上來 ,itemPricee,itemNumber); //現在補上 dq_inventory.push_back(inventory); } 補充說明(Supplement): 整段程式碼因為滿大的就不先PO上來 如果需要全部的話我再想辦法用上來 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 123.110.45.103 ※ 編輯: jack710619 來自: 123.110.45.103 (11/19 03:46)
johnpage:while? ,放後面 11/19 05:43
soheadsome:while(fileinput) 不就好了嗎 11/19 08:53
我寫成do-while迴圈也是一樣 換成while(fileInput)做判斷也是一樣會多輸入一次最後一行
LPH66:FAQ: .eof() 只在上一次讀取失敗時為 true 11/19 08:58
LPH66:如果後面沒資料但還沒去讀的話 .eof() 為 false 11/19 08:59
LPH66:其實這個觀念可以這樣想: 還沒去看(讀取)哪知道後面沒資料? 11/19 09:04
LPH66:當然是看過了沒發現(讀取失敗)才知道沒資料 11/19 09:04
所以意思就是說用 .eof()來寫一定會多跑一次囉? 那如果我不想要多跑那一次有什麼方法嗎? 噢還有我改成do{...}while(fileInput);來寫也是會多讀一次 ※ 編輯: jack710619 來自: 123.110.45.103 (11/19 13:27) ※ 編輯: jack710619 來自: 123.110.45.103 (11/19 13:29)
pziyout:用while ( fileInput >> itemName >> itemPrice >> ... ) 11/19 13:32
那這樣用了while的內容要再打一次嗎? 因為我是第一次看見這樣的寫法 ※ 編輯: jack710619 來自: 140.120.13.43 (11/19 14:06)
LPH66:這種寫法就是 fileInput >> ... 讀取之後 11/19 15:57
LPH66:它會回傳 fileInput 物件的參考回來 11/19 15:58
LPH66:把它當布林值判斷就是檢查這物件有沒有被標記問題 11/19 15:58
LPH66:true 表示沒問題 也就是剛才讀取成功了 11/19 15:58
LPH66:false 則是有問題 代表剛才讀取失敗 11/19 15:59
pziyout:多看幾次,以後自然會這樣寫 :-) 同時比 eof 很簡單多了。 11/19 17:06
pziyout:缺點是一次讀多筆資料,若中間有誤,就不知哪筆資料出問題 11/19 17:08
soheadsome:推樓上 這就是c++的多載運算子的好處 很多事情就變簡單 11/19 19:54
linotwo:http://ideone.com/IcVSnU 11/19 20:30
linotwo:Check the failbit before pushing into the queue. 11/19 20:31
pziyout:你輸入的部份也沒寫對,當資料存入 itemName , itemPrice 11/20 12:11
pziyout:後,並沒存入 inventory 物件內,如何將之存入 deque ? 11/20 12:13
這個部份是我忘記打上來了 SOR 我自己寫的code裡面是有寫的 ※ 編輯: jack710619 來自: 123.110.45.103 (11/20 12:59) ※ 編輯: jack710619 來自: 123.110.45.103 (11/20 13:03)