【发布时间】:2012-02-29 13:57:30
【问题描述】:
这个小的自定义 getline 函数以 answer 的形式提供给有关处理不同行尾的问题。
该函数运行良好,直到 2 天前对其进行了编辑,使其不会跳过每行的前导空格。然而,在编辑之后,程序现在进入一个无限循环。对代码所做的唯一更改是以下行:
std::istream::sentry se(is); // When this line is enabled, the program executes
// correctly (no infinite loop) but it does skip
// leading white spaces
到这里:
std::istream::sentry se(is, true); // With this line enabled, the program goes
// into infinite loop inside the while loop
// of the main function.
如果我们指定不跳过空格,有人可以帮我解释为什么程序会无限循环吗?
这是完整的程序...
std::istream& safeGetline(std::istream& is, std::string& t)
{
t.clear();
// The characters in the stream are read one-by-one using a std::streambuf.
// That is faster than reading them one-by-one using the std::istream.
// Code that uses streambuf this way must be guarded by a sentry object.
// The sentry object performs various tasks,
// such as thread synchronization and updating the stream state.
std::istream::sentry se(is, true);
std::streambuf* sb = is.rdbuf();
for(;;) {
int c = sb->sbumpc();
switch (c) {
case '\r':
c = sb->sgetc();
if(c == '\n')
sb->sbumpc();
return is;
case '\n':
case EOF:
return is;
default:
t += (char)c;
}
}
}
这是一个测试程序:
int main()
{
std::string path = "end_of_line_test.txt"
std::ifstream ifs(path.c_str());
if(!ifs) {
std::cout << "Failed to open the file." << std::endl;
return EXIT_FAILURE;
}
int n = 0;
std::string t;
while(safeGetline(ifs, t)) //<---- INFINITE LOOP happens here. <----
std::cout << "\nLine " << ++n << ":" << t << std::endl;
std::cout << "\nThe file contains " << n << " lines." << std::endl;
return EXIT_SUCCESS;
}
我也尝试在函数的最开始添加这一行,但没有任何区别......程序仍然在main函数的while循环中无限循环。
is.setf(0, std::ios::skipws);
文件end_of_line_test.txt是一个文本文件,只包含以下两行:
"1234" // A line with leading white spaces
"5678" // A line without leading white spaces
【问题讨论】:
-
@templatetypedef 我正在使用最新版本的命令行编译器,用于在 windows xp 32 位上运行的 Visual c++。如果我将哨兵行更改为“std::istream::sentry se(is);”该程序有效,但如果我将其改回“std::istream::sentry se(is, true);”程序崩溃。在您的测试文件中,您是否在任何行中有前导空格?
-
您遇到了什么具体的崩溃问题?我们可以得到堆栈跟踪吗?
-
我更改了 while 循环内的行以演示崩溃。我得到一个无休止的打印输出,显示 t 的内容的行号和数字零。我不知道如何进行堆栈跟踪(初学者,抱歉)。
-
@templatetypedef 非常抱歉,我遇到了无限循环。我将编辑我的问题以进行更正。
-
我已经更新了原始答案stackoverflow.com/questions/6089231/…中的代码现在一切正常。