作者jack710619 (呵呵呵)
看板C_and_CPP
標題[問題] 關於C++的檔案處理
時間Tue Nov 19 03:45:35 2013
開發平台(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: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)