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

时间:2011-01-21 00:51:11

标签: 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.
        }
    }

3 个答案:

答案 0 :(得分: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.
    }
}

主要更改以内联标记,但总结一下:

  1. 在while循环中使用读取操作作为测试。这使代码更短更清晰。
  2. 不要将C风格的字符串转换为std::string;只需使用strstr进行扫描。
  3. 另外请注意,除非你确定这是你想要的,否则你可能不想在这里使用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.
        }
    }
    

答案 1 :(得分:3)

在代码中,首先将文件中的字符复制到char数组中。这应该是所有必要的复制。如果您需要阅读每个字符一次,那么即使是那个副本也不是必需的。

接下来,从您填充的数组中构造std::string。再一次,没必要。如果你想要一个字符串,那么从流中直接复制到一个字符串。

std::ifstream f("/file/on/disk");
for( std::string line; std::getline(f, line); ) {
    if (str.find(pattern) != std::string::npos) {
        // further processing, then break out of the while loop and return.
    }
}

答案 2 :(得分:1)

您根本不需要char[]

string line;
std::getline(f, line);
if (line.find(pattern) != std::string::npos)
{
    ....
}