【发布时间】:2008-10-19 05:48:48
【问题描述】:
我正在解析一个输入文本文件。如果我使用 getline() 一次获取一行输入,有没有一种方法可以搜索字符串以获取整数?我在想类似于 Java 中的 getNextInt() 的东西。
我知道该输入行中必须有 2 个数字;但是,这些值会被一个或多个空格字符分隔,所以我不能只转到特定位置。
【问题讨论】:
我正在解析一个输入文本文件。如果我使用 getline() 一次获取一行输入,有没有一种方法可以搜索字符串以获取整数?我在想类似于 Java 中的 getNextInt() 的东西。
我知道该输入行中必须有 2 个数字;但是,这些值会被一个或多个空格字符分隔,所以我不能只转到特定位置。
【问题讨论】:
有几点需要考虑:
假设每行有两个数字,后面跟着你不关心的文本。
while(inFile >> rows >> columns)
{
// Successfully read rows and columns
// Now remove the extra stuff on the line you do not want.
inFile.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
}
还要注意,如果分隔整数值的唯一因素是“空白”,那么您甚至不需要使用 ignore() 行。
上面的 while() 之所以有效,是因为:运算符 >> 返回一个流对象(引用)。因为流对象在布尔上下文中使用,编译器会尝试将其转换为布尔值,并且流对象有一个转换运算符来执行该转换(通过在流上调用 good())。
需要注意的重要一点是不要使用该行
while(inFile.eof())
如果你确实使用它,那么你就会陷入最后一行问题的陷阱。如果您已阅读所有数据,则 eof() 仍然是错误的(因为在您尝试阅读过去的 EOF 之前它是不正确的)。所以文件中没有任何数据,但您仍然输入循环体。然后在您的代码中执行 getline() 并失败(没有更多数据),现在设置了 EOF。循环的其余部分将取决于 inLine 的定义方式和位置。
你可以像上面一样使用这个测试。但你也必须愿意在使用后测试流是否正常。
while(inFile.eof()) // Should probably test good()
{
getLine(inFile,inputline);
if(inFile.eof()) // should probably test good()
{
break;
}
}
【讨论】:
while (stream) 测试的条件相同(除了相反)。
如果里面只有空格和整数,试试这样:
int i1, i2;
stringstream ss(lineFromGetLine);
ss >> i1 >> i2;
或更简单:
int i1, i2;
theFileStream >> i1 >> i2;
【讨论】:
char* 构造字符串流,就像从std::string 构造一样容易。如果您有不同的问题,请提出新的问题。但不要对随机答案投反对票。
这不仅仅是一点点 C-ish,但您可以在 C 字符串表示上使用 sscanf()。或者您可以使用 strtol() 或亲属 - 也在 C 字符串表示上。
更 C++ 的方式可能会使用字符串流和提取器。
【讨论】:
我试过了:
while (!inFile.eof()) {
getline (inFile,inputLine);
stringstream ss(inputLine);
ss >> rows >> columns;
}
我收到以下错误:
“术语不计算为带 1 个参数的函数”在行
ss(输入线);
edit:所以你必须在你给它参数的那一刻声明字符串流。更正了上面编辑的代码。
【讨论】:
永远不要使用 .eof() 来测试你是否可以阅读,也不要使用 .eof() 来测试之前的阅读是否失败。这两种方法在某些情况下都会失败,因为:
一般来说,您应该只在读取失败后使用 .eof() 来检查失败是否是由输入结束引起的。
使用while (std::getline(...)) 循环遍历行。
【讨论】: