在 Linux 中编译的程序未检测到 fstream 中的“\n”换行符,而 Windows 运行时检测到

Program compiled in Linux doesn't detect '\n' line breaks in fstream where Windows runtime does

已编辑:

在我的代码的某些部分,我在 fstream 上使用 peek() 函数来查看打开的 .txt 文件中的下一个字符是否是一个换行符,我认为这是定义的在我的 .txt 文件中作为字符 \n。当在 Windows 中编译并 运行 时,我的程序 运行 正常运行,并将打开的文件中的每个换行符解释为 \n。但是,当我 运行 在 Linux 中使用 g++ 编译的相同程序时,我的 if (file.peek() != '\n') 语句 return true 当当前位置位于 a 的末尾时文件中的行(不正确),其中 Windows return 编辑了与 false 相同的语句(正确)。为什么是这样? 在 Linux 和 Windows 中打开的 .txt 文件中,新行是否由 \n 以外的字符定义?

代码片段:

if (counter % 5 == 0){
    cout << "counter % 5 = " << counter % 5 << endl;
    cout << "counter = " << counter << ". " << "true: (counter % 5 == 0)" << endl;
    if (counter < 125){
        cout << "counter = " << counter << ". " << "true: (counter < 25)" << endl;
        if (file.peek() != '\n'){
            cout << "counter = " << counter << ". " << "returned false on (file.peek() != \'\n\')" << endl;
            return false;
        }
    }
}

终端输出 (g++):

counter % 5 = 0
counter = 5. true: (counter % 5 == 0)
counter = 5. true: (counter < 25)
counter = 5. returned false on (file.peek() != '\n')

这是我试图以字符串形式复制的 .txt 文件:

test.txt:

1 1 0 1 0
0 0 0 1 0
1 1 1 1 0
1 0 0 0 0
1 0 0 0 0

0 1 0 1 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
1 0 0 0 0

0 1 0 1 0
0 1 0 0 0
0 1 1 1 0
0 0 0 0 0
1 0 0 0 0

0 0 0 1 0
0 0 0 0 0
0 0 0 1 0
0 0 0 0 0
1 0 0 0 0

0 0 0 1 0
0 0 0 1 0
0 0 0 1 0
0 0 0 0 0
1 1 1 1 1

Main.cpp:

#include <fstream>
#include <string>
#include <iostream>
#pragma once

using namespace std;

bool importMaze(string file_name){
    fstream file;
    string inMaze = "";
    string finalMaze = "";
    int counter = 1;

    file.open(file_name.c_str());

    while (file >> inMaze){
        bool noSpace = false;
        bool addLine = false;
        bool addSecondLine = false;

        if (inMaze != "0" && inMaze != "1"){
            cout << "counter = " << counter << ". " << "returned false on (inMaze != \"0\" && inMaze != \"1\")" << endl;
            return false;
        }
        if (counter == 1 && inMaze != "1"){
            cout << counter << ": " << "returned false on (counter == 1 && inMaze != \"1\")" << endl;
            return false;
        }
        if (counter == 125 && inMaze != "1"){
            cout << "counter = " << counter << ". " << "returned false on (counter == 125 && inMaze != \"1\")" << endl;
            return false;
        }
        if (counter % 5 != 0 && file.peek() == '\n'){
            cout << "counter = " << counter << ". " << "false on (counter % 5 != 0 && file.peek() == \'\n\')" << endl;
            return false;
        }
        if (counter % 5 == 0 && counter < 125 && file.peek() == '\n'){
            addLine = true;
            noSpace = true;
            if (counter % 25 != 0){
                file.seekg(2, ios::cur);
                char test = file.peek();
                if (file.peek() == '\n'){
                    cout << "counter = " << counter << ". " << "returned false on counter % 25 != 0 and (file.peek() == \'\n\')" << endl;
                    return false;
                }
                file.seekg(-2, ios::cur);
            }
            if (counter % 25 == 0 && counter < 125){
                file.seekg(1, ios::cur);
                if (file.peek() == '\n'){
                    addSecondLine = true;
                }
                if (file.peek() != '\n'){
                    cout << "counter = " << counter << ". " << "returned false on counter % 25 == 0 and (file.peek() != \'\n\')" << endl;
                    return false;
                }
            }
        }

        /** Returns false when should be true */

        if (counter % 5 == 0){
            cout << "counter % 5 = " << counter % 5 << endl;
            cout << "counter = " << counter << ". " << "true: (counter % 5 == 0)" << endl;
            if (counter < 125){
                cout << "counter = " << counter << ". " << "true: (counter < 25)" << endl;
                if (file.peek() != '\n'){
                    cout << "counter = " << counter << ". " << "returned false on (file.peek() != \'\n\')" << endl;
                    return false;
                }
            }
        }

        /** ^^ Returns false when shoulld be true ^^ */

        if (counter == 125 && file.peek() == '\n'){
            cout << "counter = " << counter << ". " << "returned false on (counter == 125 && file.peek() == \'\n\')" << endl << "inMaze:" << endl << inMaze << endl << "finalMaze:" << finalMaze << endl;
            return false;
        }
        if (counter == 125){
            noSpace = true;
        }
        finalMaze += inMaze;
        if (noSpace == false){
            finalMaze += " ";
        }
        if (addLine == true){
            finalMaze += "\n";
        }
        if (addSecondLine == true){
            finalMaze += "\n";
        }
        inMaze.clear();
        counter++;
    }
    cout << finalMaze;
    return true;
}

int main(){

    importMaze("test.txt");
}

您声称:

I cout what counter % 5 computes to (0) and it still marks if (counter % 5 == 0) statement as false!

但这是无稽之谈。您打印 "false on" 字样,但这并不意味着它实际上是错误的。 if 条件计算结果为真,否则它不会打印任何东西! counter % 5 为零,即假,但 counter % 5 == 0 为真。

使用您自己的 tutorialspoint.com link 我 运行 file test.txt 在 shell 提示符下得到:

test.txt: ASCII text, with CRLF line terminators

所以问题是 DOS 风格的行尾,与不知道如何编译 C++ 的 g++ 无关(这应该是显而易见的,因为 g++ 是一个优秀的编译器并且更有可能正确地使用 C++比你还厉害!见 the first rule of programming)

您误解了该行不以 \n 结尾的事实,并指责编译器做错了算术。文件流以文本模式打开,这意味着在 Windows 上,运行时从 \r\n 序列中删除 \r 个字符,但在 GNU/Linux 上,文本模式和二进制模式是等效的并且输入没有被修改。您需要在代码中显式处理 \r 个字符,或者在读取文件之前修复输入文件以删除这些字符。