簡體   English   中英

由於eof在C ++中讀取了兩次文件?

[英]Read a file twice in C++ because of eof?

我從文件中讀取數字,應用3個功能並打印到另一個文件:

int main(int argc, char** argv) {
    std::ifstream fin;
    fin.open("input.txt");

    std::ofstream fout;
    fout.open("output.txt", std::ios::app);

    char arr[50];
    int a,b;
    int N;//number to factor

    while (!fin.eof()){
        //Print backward
        fin >> arr;
        PrintBackward( arr );
        fout << endl;

        //Greatest common divisor
        ((fin >> a) >> b);
        fout << gcd( a, b );
        fout << endl;

        //Find prime factor
        fin >> N;
        PrimeFactor(N);
        fout << endl;     
    }

    fin.close();
    fout.close();

    return 0;
}

運行后,結果重復:

olleh
3
2 3 7 
olleh
3
2 3 7

我讀過一篇類似的文章,但它涉及到讀入1個變量,因此似乎不可行。

如果我在while循環的末尾設置了break while ,那就沒問題了。 有什么辦法不使用break嗎?

while (!whatever.eof())本質上總是錯誤的,並且永遠不會正確檢測文件的結尾。 在您的情況下,最簡單的方法是將讀取合並在一起,然后進行所有處理,如下所示:

while (fin >> arr >> a >> b >> N) {
    PrintBackwards(arr);
    fout << "\n";

    fout << gcd(a, b) << "\n";

    fout << PrimeFactor(N) << "\n";
}

關鍵部分是檢查讀取結果,而不是彼此分開檢查和讀取。

還有幾點建議:我將使用std::string而不是數組。 我還將反轉字符串與打印字符串分開,所以您可以得到類似以下內容的內容:

fout << reverse(arr)   << "\n" 
     << gcd(a, b)      << "\n" 
     << PrimeFactor(N) << "\n";

強調操作之間的共性往往是一件好事。

編輯:只是為了好玩,我會指出另一種您可以根據需要進行操作的方式。 由於您基本上是將四個項目作為一個組進行讀取和處理,因此可以使該分組更為明確:

struct item { 
     std::string arr;
     int a, b, N;

     friend std::istream &operator>>(std::istream &is, item &i) { 
         return is >> arr >> a >> b >> N;
     }
};

struct process {
    std::string operator()(item const &i) { 
        std::ostringstream buffer;

        buffer << reverse(arr) << "\n" << gcd(a, b) << "\n" << PrimeFactor(N);
        return buffer.str();
    }
}

這樣,您就可以讓標准庫處理讀寫的所有細節,檢查文件結尾等。

std::transform(std::istream_iterator<item>(fin), 
               std::istream_iterator<item>(),
               std::ostream_iterator<std::string>(std::cout, "\n"),
               process());

我的猜測是您檢查eof的時間過早-僅在嘗試讀取且由於文件位於文件末尾而導致讀取失敗時才進行設置。 嘗試在fin >> arr之后添加此代碼:

if (fin.eof()) break;

實際上,您應該在每次IO操作之后檢查錯誤-這樣做不是草率的編碼,並且不會很健壯。

暫無
暫無

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

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