在Linux中编译的程序;t检测'n'在Windows运行时所在的fstream中换行

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

本文关键字:运行时 换行 fstream Windows 检测 Linux 编译 程序      更新时间:2023-10-16

编辑:

在我的代码的某些部分中,我在fstream上使用peek()函数来查看打开的.txt文件中的下一个字符是否是换行符,我认为它在我的.txt文件中定义为字符n。在Windows中编译和运行时,我的程序会正常运行,并将打开的文件中的每个换行符解释为n。但是,当我在Linux中运行用g++编译的同一程序时,当当前位置位于文件中的一行末尾时(不正确),我的if (file.peek() != 'n')语句返回true,Windows在该行返回了与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");
}

您声称:

我将计数器%5计算的内容设置为(0),它仍然将if(计数器%5==0)语句标记为false!

但那是胡说八道。你在上面印了"假的",但这并不意味着它实际上是假的。if条件的计算结果为true,否则它将不会打印任何内容!counter % 5为零,即为假,但counter % 5 == 0为真。

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

test.txt: ASCII text, with CRLF line terminators

所以问题是DOS风格的行尾,与g++不知道如何编译C++无关(这应该是显而易见的,因为g++是一个优秀的编译器,比你更可能正确地编译C++!参见编程的第一条规则)

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