Linux |C++中的分段错误 - 由于函数 ifstream
Linux | Segmentation Fault in C++ - Due to the function ifstream
我想我应该首先说我刚刚在我的电脑上安装了linux(debian(,并且对在Linux中做事没有任何预知。这个问题可能是由于一些非常简单的事情。
代码的相关部分类似于以下内容:
ifstream stockNames("names.txt");
while (!stockNames.eof())
{
string snline;
getline(stockNames,snline);
cout << snline << endl;
.
.
.
}
这应该打印文件"名称.txt"的第一行。相反,它会打印一个空行。当我尝试在另一个函数中使用snline作为输入时,我收到错误"分段错误"。我应该如何修改我的代码来执行此操作?ifstream在linux中的使用有什么区别吗?因为在窗口中代码工作正常
我在下面编写了简单的代码
#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;
}
名称的内容.txt是
美国广播公司
德夫格
高压氧
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不会出现,唯一的输出是"嘿"。
这太疯狂了,这怎么可能??
顺便说一句,我尝试使用 ddd 进行调试,当我检查变量 snline 时,ddd 打印以下行(gdb( 打印 SNLINE$2 = {静态 npos = 4294967295, _M_dataplus = {> = {<__gnu_cxx::new_allocator> = {}, }, _M_p = 0x804c1a4 "ABC\r"}}
新的迷你更新:当我将相关行更改为"cout <<snline <<""<<endl;"时,打印出来的是"BC"FGH"BO"在单独的行中。为什么<<运算符会覆盖 snline?
首先,你的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 << " ";
}
现在运行它,看看它打印了什么。
您有一个在每行末尾使用 \r 的 dos 文件。Linux 不识别 \r 作为行尾的一部分,因此它包含在 snline 字符串中。\r 使打印的下一项出现在行首,因此"hey"会覆盖您期望看到的股票名称。
尝试
cout << snline << " " << endl;
你会明白我的意思
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;
.
.
.
}
回答你的问题;不,ifstream在Linux和Windows上的运行方式没有显着差异。当然,如果你写了错误的代码(正如其他两个答案所指出的那样(,那么你可能会遇到问题,但我看不出 eof bug 会导致你所描述的问题。
我会专注于您说使用 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;
是你在很多试图节省少量墨水的坏书中看到的东西。试着摆脱这个坏习惯。
- 是 C++ gcc HEAD 10.0.0 20190 相对于好友函数的错误吗?
- STD ::在模板函数中应用于构造函数
- 使自由函数的行为类似于成员函数 (C++)
- 可以将属性应用于构造函数参数
- 严格别名规则是否适用于跨函数调用
- 为什么"return 0"适用于在函数中返回指针,但不适用于参考?
- 将自适应阈值应用于范围函数 opencv c++
- 创建独立于构造函数的对象指针
- 在本地将 'using std::foo' 指令应用于构造函数初始值设定项列表 (C++)
- Java等效于NTOHLL函数
- 什么是等效于Unix函数gmtime_r的Windows
- 当大括号初始值设定项列表中是否有序列点应用于构造函数时
- 外部声明变量的定义适用于一个函数,但不适用于另一个函数
- 否除非依赖于成员函数的否
- cin.getline() 等效于从函数获取字符时
- 等效于 std 函数对象的泛型
- 引用性不依赖于模板函数中的类型
- C++:为什么成员函数优先于全局函数
- 依赖于构造函数参数的类方法的特殊实现
- 编译器如何知道vtable中的哪个表项对应于虚函数?< / h1 >