C++ 什么';使用ifstream解析文本的惯用方法是什么?

C++ 什么';使用ifstream解析文本的惯用方法是什么?,c++,idioms,C++,Idioms,我试图解析一个文本文件,找到一个模式,然后获取一个子字符串。这个代码片段工作得很好,但是我可以改进它吗?我可以在这里复制吗?也就是说,我得到一行并将其存储在buf中,然后构造一个字符串,可以消除这种复制吗 简而言之,实现这一目标的惯用方法是什么 std::ifstream f("/file/on/disk"); while (!f.eof()) { char buf[256]; f.getline(buf, sizeof(buf));

我试图解析一个文本文件,找到一个模式,然后获取一个子字符串。这个代码片段工作得很好,但是我可以改进它吗?我可以在这里复制吗?也就是说,我得到一行并将其存储在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.
        }
    }

这里有一个可能的重写:

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.
    }
}
主要更改标记为内联,但概括起来:

  • 使用读取操作作为while循环中的测试。这使得代码更加简短和清晰
  • 不要将C样式字符串强制转换为
    std::string
    ;只需使用
    strstr
    进行扫描
  • 作为进一步说明,您可能不想在这里使用C样式的字符串,除非您确定这是您想要的。一个C++ <代码>字符串可能更好:

    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.
        }
    }
    

    这里有一个可能的重写:

    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.
        }
    }
    
    主要更改标记为内联,但概括起来:

  • 使用读取操作作为while循环中的测试。这使得代码更加简短和清晰
  • 不要将C样式字符串强制转换为
    std::string
    ;只需使用
    strstr
    进行扫描
  • 作为进一步说明,您可能不想在这里使用C样式的字符串,除非您确定这是您想要的。一个C++ <代码>字符串可能更好:

    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.
        }
    }
    

    你根本不需要那种
    char[]

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

    你根本不需要那种
    char[]

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

    在代码中,首先将文件中的字符复制到
    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.
        }
    }
    

    在代码中,首先将文件中的字符复制到
    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.
        }
    }
    

    测试
    f.eof()
    绝对不是惯用语。测试
    f.eof()
    绝对不是惯用语。噢,穷人滥用
    ,因为
    loop@Ben字体我不知道,我有点喜欢。我没有将初始化语句理解为“声明正在计数的内容”,而是将其理解为“声明与循环相关的内容”。@Ben:我喜欢这样。以前没有想过,但这似乎是一种非常严格的方法,可以确保线路不会泄漏到使用限制之外。哦,穷人滥用
    loop@Ben字体我不知道,我有点喜欢。我没有将初始化语句理解为“声明正在计数的内容”,而是将其理解为“声明与循环相关的内容”。@Ben:我喜欢这样。以前没有想过,但这似乎是一个非常严格的方法,以确保线路不会泄漏到使用限制之外。