使用ifstream解析文本的惯用方法是什么?

gro*_*kus 1 c++ idiomatic

我正在尝试解析文本文件以查找模式然后获取子字符串.这段代码片段运行正常,但我可以改进吗?我可以在这里最小化复制吗 即我得到一行并将其存储在buf然后构造一个字符串,这个复制可以被删除吗?

简而言之,实现这一目标的惯用方法是什么?

    std::ifstream f("/file/on/disk");
    while (!f.eof()) {
        char buf[256];
        f.getline(buf, sizeof(buf));
        std::string str(buf);
        if (str.find(pattern) != std::string::npos)
        {
            // further processing, then break out of the while loop and return.
        }
    }
Run Code Online (Sandbox Code Playgroud)

tem*_*def 5

这是一个可能的重写:

std::ifstream f("/file/on/disk");
char buffer[256];
while (f.getline(buffer, sizeof(buf))) { // Use the read operation as the test in the loop.
    if (strstr(buffer, pattern) != NULL) { // Don't cast to string; costs time
        // further processing, then break out of the while loop and return.
    }
}
Run Code Online (Sandbox Code Playgroud)

主要变化是内联标记,但总结如下:

  1. 使用read操作作为while循环中的测试.这使代码更短更清晰.
  2. 不要将C风格的字符串转换为std::string; 只是strstr用来做扫描.

另外请注意,除非你确定这是你想要的,否则你可能不想在这里使用C风格的字符串.C++ string可能更好:

std::ifstream f("/file/on/disk");
std::string buffer;
while (std::getline(f, buffer)) { // Use the read operation as the test in the loop.
    if (buffer.find(pattern) != std::string::npos) {
        // further processing, then break out of the while loop and return.
    }
}
Run Code Online (Sandbox Code Playgroud)