[問題] 關於C++的檔案處理

看板C_and_CPP (C/C++)作者 (呵呵呵)時間12年前 (2013/11/19 03:45), 編輯推噓7(7012)
留言19則, 5人參與, 最新討論串1/2 (看更多)
開發平台(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)

11/19 05:43, , 1F
while? ,放後面
11/19 05:43, 1F

11/19 08:53, , 2F
while(fileinput) 不就好了嗎
11/19 08:53, 2F
我寫成do-while迴圈也是一樣 換成while(fileInput)做判斷也是一樣會多輸入一次最後一行

11/19 08:58, , 3F
FAQ: .eof() 只在上一次讀取失敗時為 true
11/19 08:58, 3F

11/19 08:59, , 4F
如果後面沒資料但還沒去讀的話 .eof() 為 false
11/19 08:59, 4F

11/19 09:04, , 5F
其實這個觀念可以這樣想: 還沒去看(讀取)哪知道後面沒資料?
11/19 09:04, 5F

11/19 09:04, , 6F
當然是看過了沒發現(讀取失敗)才知道沒資料
11/19 09:04, 6F
所以意思就是說用 .eof()來寫一定會多跑一次囉? 那如果我不想要多跑那一次有什麼方法嗎? 噢還有我改成do{...}while(fileInput);來寫也是會多讀一次 ※ 編輯: jack710619 來自: 123.110.45.103 (11/19 13:27) ※ 編輯: jack710619 來自: 123.110.45.103 (11/19 13:29)

11/19 13:32, , 7F
用while ( fileInput >> itemName >> itemPrice >> ... )
11/19 13:32, 7F
那這樣用了while的內容要再打一次嗎? 因為我是第一次看見這樣的寫法 ※ 編輯: jack710619 來自: 140.120.13.43 (11/19 14:06)

11/19 15:57, , 8F
這種寫法就是 fileInput >> ... 讀取之後
11/19 15:57, 8F

11/19 15:58, , 9F
它會回傳 fileInput 物件的參考回來
11/19 15:58, 9F

11/19 15:58, , 10F
把它當布林值判斷就是檢查這物件有沒有被標記問題
11/19 15:58, 10F

11/19 15:58, , 11F
true 表示沒問題 也就是剛才讀取成功了
11/19 15:58, 11F

11/19 15:59, , 12F
false 則是有問題 代表剛才讀取失敗
11/19 15:59, 12F

11/19 17:06, , 13F
多看幾次,以後自然會這樣寫 :-) 同時比 eof 很簡單多了。
11/19 17:06, 13F

11/19 17:08, , 14F
缺點是一次讀多筆資料,若中間有誤,就不知哪筆資料出問題
11/19 17:08, 14F

11/19 19:54, , 15F
推樓上 這就是c++的多載運算子的好處 很多事情就變簡單
11/19 19:54, 15F

11/19 20:30, , 16F
11/19 20:30, 16F

11/19 20:31, , 17F
Check the failbit before pushing into the queue.
11/19 20:31, 17F

11/20 12:11, , 18F
你輸入的部份也沒寫對,當資料存入 itemName , itemPrice
11/20 12:11, 18F

11/20 12:13, , 19F
後,並沒存入 inventory 物件內,如何將之存入 deque ?
11/20 12:13, 19F
這個部份是我忘記打上來了 SOR 我自己寫的code裡面是有寫的 ※ 編輯: jack710619 來自: 123.110.45.103 (11/20 12:59) ※ 編輯: jack710619 來自: 123.110.45.103 (11/20 13:03)
文章代碼(AID): #1IYcvYCj (C_and_CPP)
討論串 (同標題文章)
文章代碼(AID): #1IYcvYCj (C_and_CPP)