在std::istream中跳过行

13

我正在使用std::getline()从一个继承自std::istream的类中读取行,如何向前移动几行?

我只需要读取并丢弃它们吗?

3个回答

21

不,你不必使用getline

更高效的方法是使用std::istream::ignore忽略字符串

for (int currLineNumber = 0; currLineNumber < startLineNumber; ++currLineNumber){
    if (addressesFile.ignore(numeric_limits<streamsize>::max(), addressesFile.widen('\n'))){ 
        //just skipping the line
    } else 
        return HandleReadingLineError(addressesFile, currLineNumber);
}

HandleReadingLineError不是标准的,但是当然可以自己制作。第一个参数是最大要提取的字符数。如果这个数字恰好为numeric_limits::max(),那么就没有限制:

链接到cplusplus.com:std::istream::ignore

如果你打算跳过很多行,你绝对应该使用它而不是getline:当我需要跳过文件中的100000行时,它只需要大约1秒钟,而用getline则需要22秒钟。


12

编辑:你也可以使用std::istream::ignore,参见https://dev59.com/hnE85IYBdhLWcg3w2HXs#25012566


我是否必须使用getline才能跳过我想要的行数?

不是必需的,但对于阅读您的代码的人来说,这可能是最清晰的解决方案。如果要跳过的行数很多,您可以通过读取大块并计算每个块中的换行符数量来提高性能,然后在最后一个换行符的位置停止并重新定位文件。但是,除非您遇到性能问题,否则我建议只需将getline放入循环中以跳过所需的行数。


3
计算换行符的方法类似于一个循环使用getline,对吧? - GManNickG
@GMan - 拯救独角兽:是的,但如果您知道n很大(即在缓冲块中计数多个换行符),则可以使用更大的块并向前移动更大的距离。 - Billy ONeal
如果我将整个文件加载到内存中,并使用正则表达式解析它会怎样?文件不到1MB。 - ufk

8

如果您不知道换行符的位置,请使用std::getline

如果您偶然知道换行符出现的位置,则可以先使用ifstream::seekg

您可以使用其他方法进行读取,例如ifstream::read,但是std::getline可能是最简单和最清晰的解决方案。


@Billy:其实你的迟到让我多得了10个声望值,因为我在10分钟前已经达到了最大上限。 - Brian R. Bondy
哈哈!我还没有撞到这个限制。 - Billy ONeal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接