簡體   English   中英

從ifstream讀取時多余的空行

[英]extraneous empty lines when reading from an ifstream

在我的程序中,我已將標准輸出重定向到打印到文件“ console.txt”。 函數將如下所示寫入該文件:

void printToConsole(const std::string& text, const TCODColor& fc, const TCODColor& bc)
    {
        // write the string
        cout << text << "@";

        // write the two color values
        cout << static_cast<int>(fc.r) << " "
             << static_cast<int>(fc.g) << " " 
             << static_cast<int>(fc.b) << " "
             << static_cast<int>(bc.r) << " "
             << static_cast<int>(bc.g) << " " 
             << static_cast<int>(bc.b) << " " << endl;
    }

我有一個從該文件讀取的函數,如下所示:

   void Console::readLogFile()
   {
        ifstream log("console.txt", ifstream::in);
        if(!log.is_open())
        {
            cerr << "ERROR: console.txt not found!" << endl;
            return;
        }

        // read new input into the stack
        char str[256];
        while(!log.eof())
        {
            log.getline(str, 256);
            cerr << "str: " << str << endl;
            stk.push(static_cast<string>(str));
            // stk is a std::stack<std::string> member of the class this function
            // belongs to.
        }
        cerr << endl;

        /* Do some stuff with str and stk here */

        log.close();
        clearLogFile();
    }

    void Console::clearLogFile()
    {
        FILE* log;
        log = fopen("console.txt", "w");
        fclose(log);
    }

通常,在readLogFile時console.txt為空。 我希望在那種情況下while(!log.eof())循環永遠不會執行,但是確實可以。 文件中總是至少有一個多余的空白行,有時是兩個,並且從文件中讀取輸入時,輸入行夾在兩個空白行之間。 幾次調用此函數后, while(!log.eof())循環進入無限循環,從文件中拉出空白行。 該程序的典型運行過程如下所示:

str: 

str: Player moved.@191 191 191 0 0 0
str: 

str: 
str: Player moved.@191 191 191 0 0 0 
str: 

str: // there should be a 'Player moved.' line in here
str:

str: // here as well
str:

str: // also here
str:

str: 
str: Player moved.@191 191 191 0 0 0 
str: 

str:
str:
str:
str:
str:
str:
(onto infinite loop)

誰能看到我在這里做錯了什么?

編輯:如Amardeep所建議,我將while(!log.eof())循環更改為do{...}while(!log.fail); 環。 這解決了無限循環問題,但沒有解決多余的問題。 該程序的行為與以前相同,除了它曾經進入無限循環的地方外,它現在只讀取應讀取輸入的空白​​行,如下所示:

str:

str:

str:

str: 
(etc.)

嘗試讀取之前,不會設置eof()狀態。 您應該更改讀取循環以執行getline(),然后檢查fail()狀態,而不要依賴eof(),因為eof()不能解決嘗試讀取文件時可能出錯的問題。

用於讀取文件的標准反模式。

    while(!log.eof())
    {
        log.getline(str, 256);
        cerr << "str: " << str << endl;
        stk.push(static_cast<string>(str));
        // stk is a std::stack<std::string> member of the class this function
        // belongs to.
    }

嘗試這個:

    while(log.getline(str, 256))
    {
        cerr << "str: " << str << endl;
        stk.push(string(str));
    }

之所以可行,是因為getline()方法返回對該流的引用。

當在布爾上下文中使用流時,它將轉換為布爾值(不是真正的學徒,而是初學者)。 如果流在讀取后仍處於良好狀態(即讀取有效),則將其轉換為true。 如果流處於不良狀態(即讀取失敗),則將其轉換為false。 因此,如果讀取成功,則進入循環。 如果讀取失敗(因為可能讀取了EOL),則不會進入循環。

請注意,您的版本失敗了,因為在讀取(getline())之后未測試eof()。 之所以這樣,是因為最后一次讀操作會讀取直到EOF的所有字符。 但這意味着未設置eof標志。 直到您嘗試實際讀取EOF為止(只有在最后一次讀取后讀取了所有其他字符之后才讀取某些內容),才會設置EOF標志。

PS。 有一個免費功能,可以從流中讀取字符串。

std::string line;
std::getline(log, line);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM