2013-07-31 191 views
3

這個問題困擾了我一個晚上。謝謝!C++ getline()和文件EOF

這段代碼會將最後一行寫入文件中兩次.WHY?

#include <iostream> 
#include <fstream> 
#include <string.h> 
using namespace std; 
const int strSize = 1000; 
int main(int argc,char *argv[]) 
{ 
    ifstream infile(argv[1]); 
    if(!infile) cerr<<"infile error!"<<endl; 
    ofstream outfile(argv[2]); 

    int sequenceNum = 1; 
    char str[strSize]; 
    while(infile){ 
     infile.getline(str,strSize); 
     if(sequenceNum>469) 
      str[0] = '2'; 
     else if(sequenceNum>67) 
      str[0] = '4'; 
     else if(sequenceNum>1) 
      str[0] = '1'; 
     else 
      str[0] = '3'; 
     outfile<<str<<endl; 
     ++sequenceNum; 
    } 
    return 0; 
} 

infile.getline(str,strSize);strNULL,如果str沒有被修改,爲什麼是空?但在if(sequenceNum>469)之後,str成爲最後一行。

此代碼只寫最後一行。

#include <iostream> 
#include <fstream> 
#include <string.h> 
using namespace std; 
const int strSize = 1000; 
int main(int argc,char *argv[]) 
{ 
    ifstream infile(argv[1]); 
    if(!infile) cerr<<"infile error!"<<endl; 
    ofstream outfile(argv[2]); 

    int sequenceNum = 1; 
    char str[strSize]; 
    while(infile){ 
     infile.getline(str,strSize); 
     if(strlen(str) != 0){//The key is this sentence. 
      if(sequenceNum>469) 
       str[0] = '2'; 
      else if(sequenceNum>67) 
       str[0] = '4'; 
      else if(sequenceNum>1) 
       str[0] = '1'; 
      else 
       str[0] = '3'; 
      outfile<<str<<endl; 
      ++sequenceNum; 
     } 
    } 
    return 0; 
} 

回答

9

問題是,當infile.getline讀取的最後一行(即它讀取直到EOF),while(infile)仍然會評估爲true,從而導致循環中再次運行。但是,由於infile已讀取整個文件,所以infile.getline將失敗,str將變爲空字符串。但是,由於您的原始代碼會覆蓋第一個字符,因此它將刪除空終止符,因此會重新使用上次的內容。

相反,你想要的東西,如:

while (infile.getline(str, strSize)) { 
    if (sequenceNum>469) 
    ... 
} 
2

麻煩的是,你讀過的最後一行後,infile仍計算爲true。只有在您嘗試(並失敗)讀取另一行後,它纔會評估爲false;您的for循環進行測試讀取打印,因此無法在退出之前讀取並打印str的舊內容。

試試這個:

while(infile.getline(str,strSize)) 
    ... 
-1

從我看到的描述,它看起來像當它擊中一個行結束之前到達文件末尾,eofbit被設定。它沒有說明在這種情況下輸出字符串的狀態,所以可能的實現是它可能不會被修改。

因此,在這種情況下,如果您不檢查eof並只是打印字符串,它可能仍然具有上次調用後的內容。

您在流上進行的檢查不是「我在文件末尾?」,而是「流仍處於有效狀態?」它只會在EOF失效時纔會失效,然後再次嘗試從中讀取。

因此,您可以通過檢查infile.eof()來避免雙線。不幸的是,你仍然失去了最後一行。就我所知,解決這個問題的唯一方法是要麼堅持沒有人在最後一行放置任何重要的字符,要麼不要使用getline()作爲輸入讀數。

0

是的,它可以幫助

while(infile.getline(str,strSize)) ...