在 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
个字符,或者在读取文件之前修复输入文件以删除这些字符。
已编辑:
在我的代码的某些部分,我在 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
个字符,或者在读取文件之前修复输入文件以删除这些字符。