Linux | C ++中的分段错误 – 由于ifstream函数

我想我应该开始说我刚刚在我的电脑中安装了linux(debian),并且对linux中的事情没有任何的预知。 这个问题可能是由于一些非常简单的事情。

代码的相关部分与此类似:

ifstream stockNames("names.txt"); while (!stockNames.eof()) { string snline; getline(stockNames,snline); cout << snline << endl; . . . } 

这应该打印文件“names.txt”的第一行。 而是打印一个空行。 而当我尝试使用snline作为另一个函数的input时,我得到错误'Segmentation Fault'。 我应该如何修改我的代码来做到这一点? 在Linux的ifstream使用情况有什么不同吗? 因为在Windows中的代码工作得很好


我已经写了下面的简单代码

 #include <string> #include <fstream> #include <iostream> using namespace std; int main(int argc, const char *argv[]) { string dos = "names.txt"; ifstream stockNames(dos.c_str() ); string snline; while (getline(stockNames,snline)) { cout << snline << " "; } return 0; } 

names.txt的内容是

ABC

DEFG

HBO

而不是显示那些线,cout << snline什么都不产生


再一次更新:我已经写了两个更多的代码。

(1)

 #include <string> #include <fstream> #include <iostream> using namespace std; int main(int argc, const char *argv[]) { cout << "program has initiated" << endl; ifstream stockNames("names.txt"); if( !stockNames ) cout << "unable to open" << endl; string snline; while (getline(stockNames,snline)) { cout << snline << endl; } return 0; } 

结果是我想要的。 首先“计划已经启动”,然后是ABC,DEFG,HBO不同的行。 但是当我改变这部分

  cout << snline << endl; 

  cout << snline << " hey" << endl; 

然后ABC DEFG HBO不会出现,而是唯一的输出是“嘿”。

这很疯狂,这怎么可能?

顺便说一句,我试图做一个与DDDdebugging,当我检查variablessnline,DDD打印下面的行(gdb)打印snline $ 2 = {static npos = 4294967295,_M_dataplus = {> = {<__ gnu_cxx :: new_allocator> = { ,},_M_p = 0x804c1a4“ABC \ r”}}

新的迷你更新:当我将相关行更改为“cout << snline <<”“<< endl;” 打印出来的是“BC”“FGH”“BO”。 为什么<<操作符覆盖了snline?

Solutions Collecting From Web of "Linux | C ++中的分段错误 – 由于ifstream函数"

你有一个dos文件,在每行的末尾使用\ r \ n。 Linux不能识别\ r作为行尾的一部分,所以它被包含在snline字符串中。 \ r导致打印的下一个东西出现在行首,所以“嘿”覆盖你期待看到的股票名称。

尝试

 cout << snline << " " << endl; 

你会明白我的意思

首先, while循环是错误的,因为eof标志(或任何其他失败标志) 尝试从流中读取失败后被设置。 这意味着,如果尝试读取失败使用getline() ,循环不会立即退出,而循环继续这是一个严重的错误与您的代码。

所以把你的循环写成(一种惯用的方式):

 string snline; while (getline(stockNames,snline)) { cout << snline; //.. } 

std::getline返回istream& ,可以隐式转换为布尔类型。 所以,如果getline读取成功,那么返回值转换为true ,循环将继续,否则将转换为false ,循环将退出。


在你的问题编辑后,我可以说,你需要检查流对象之前使用它来从文件中读取内容。 更具体地说,你需要检查流是否已经正确初始化,并且确实已经打开了输入文件(即names.txt ),并准备从中读取数据。

所以请尝试这样做:

 //... ifstream stockNames(dos.c_str() ); if (!stockNames) { cout << "file couldn't open properly" << endl; return 0; } string snline; while (getline(stockNames,snline)) { cout << snline << " "; } 

现在运行这个,看看它打印什么。

stockNames直到尝试输入内容并接收到EOF字符才会真正达到“文件结尾”。 因此,你将要重新编写你的循环,如下所示:

 ifstream stockNames("names.txt"); string snline; getline(stockNames,snline); while (!stockNames.eof()) { cout << snline << endl; . . . getline(stockNames,snline); } 

或者很简单

 ifstream stockNames("names.txt"); string snline; while (getline(stockNames, snline)) { cout << snline << endl; . . . } 

回答你的问题; 不,在Linux和Windows上运行ifstream没有太大的区别。 当然,如果你编写错误的代码(另外两个答案已经指出),那么你可能会遇到问题,但我不明白这个错误会导致你描述的问题。

我会专注于你说使用snline导致分段错误的部分,这表示一个更严重的问题。 你可以发布代码来证明这一点吗?

您不检查流是否正确打开。

 std::ifstream stockNames("names.txt"); if (! stockNames) { std::cerr << "Unable to open file 'names.tex'\n"; } else { // Do the rest of your stuff here. } 

始终检查状态。 不要只是前进,假设一切都好。

顺便说一句, using namespace std; 是你在很多不好的书籍中看到的,这些书籍正在试图保存少量的墨水。 试着摆脱这个坏习惯。