【问题标题】:Parsing integers from a line从一行解析整数
【发布时间】:2008-10-19 05:48:48
【问题描述】:

我正在解析一个输入文本文件。如果我使用 getline() 一次获取一行输入,有没有一种方法可以搜索字符串以获取整数?我在想类似于 Java 中的 getNextInt() 的东西。

我知道该输入行中必须有 2 个数字;但是,这些值会被一个或多个空格字符分隔,所以我不能只转到特定位置。

【问题讨论】:

    标签: c++ string parsing


    【解决方案1】:

    有几点需要考虑:
    假设每行有两个数字,后面跟着你不关心的文本。

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

    【讨论】:

    • 您必须测试 good() 而是测试 fail(),这与 while (stream) 测试的条件相同(除了相反)。
    • @Roget Pate:如果 fail() 是 good() 的倒数,为什么我们可以测试 good()?
    【解决方案2】:

    如果里面只有空格和整数,试试这样:

    int i1, i2;
    stringstream ss(lineFromGetLine);
    ss >> i1 >> i2;
    

    或更简单:

    int i1, i2;
    theFileStream >> i1 >> i2;
    

    【讨论】:

    • 如何处理字符串而不是 char*
    • @Robert:我不知道你的抱怨是什么。您可以从char* 构造字符串流,就像从std::string 构造一样容易。如果您有不同的问题,请提出新的问题。但不要对随机答案投反对票。
    【解决方案3】:

    这不仅仅是一点点 C-ish,但您可以在 C 字符串表示上使用 sscanf()。或者您可以使用 strtol() 或亲属 - 也在 C 字符串表示上。

    更 C++ 的方式可能会使用字符串流和提取器。

    【讨论】:

      【解决方案4】:

      我试过了:

      while (!inFile.eof()) {
          getline (inFile,inputLine);
          stringstream ss(inputLine);
          ss >> rows >> columns;
      }
      

      我收到以下错误:

      “术语不计算为带 1 个参数的函数”在行

      ss(输入线);

      edit:所以你必须在你给它参数的那一刻声明字符串流。更正了上面编辑的代码。

      【讨论】:

        【解决方案5】:

        永远不要使用 .eof() 来测试你是否可以阅读,也不要使用 .eof() 来测试之前的阅读是否失败。这两种方法在某些情况下都会失败,因为:

        • 即使没有剩余字符,也不会设置 EOF,如果尚未尝试读取超过末尾的内容(例如,在最后一行的 getline 之后,如果末尾有换行符)
        • 如果读取操作必须在结束后查看下一个字符以确定它应该停止读取(例如,在最后一行的明线之后,如果没有换行符在结束)

        一般来说,您应该只在读取失败后使用 .eof() 来检查失败是否是由输入结束引起的。

        使用while (std::getline(...)) 循环遍历行。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-01-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-08-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多