【问题标题】:Error handling when reading integers from a file从文件中读取整数时的错误处理
【发布时间】:2016-11-20 12:25:18
【问题描述】:

抱歉这个有点初学者的问题,但我已经解决了几天,无法找到解决方案。

我基本上是从文件中读取整数,这些文件应该有一定数量的数字,为了这个问题,让我们说 40。当文件少于或多于 40 时,我可以返回错误整数。但是,如果那里碰巧有一个非数字字符,我正在努力弄清楚如何返回错误。 这就是我目前正在做的事情:

int number = 0;
int counter = 0;

while(inputstream >> number)
{
   // random stuff
   counter++;
}

if (counter < 40)
  return error;

在这一点上,我有点困惑该去哪里。当输入流不是 int 时,我的 while 循环将终止,但有两种情况可能发生这种情况,其中存在非整数字符,或者已到达文件末尾。如果我们在 eof,我的错误信息很好,并且整数少于 40。但是,如果它在某处遇到非整数,我们也可能小于 40。我希望能够确定两者之间的区别,但很难弄清楚如何做到这一点。任何帮助,将不胜感激。谢谢!

【问题讨论】:

  • 使用fail() 和/或eof() 确定解析失败的原因。
  • 阅读doc你可以看到eoffail,会帮助你。您必须能够阅读文档非常重要,这可以节省很多问题。
  • 感谢各位的帮助。事实证明,我在脑海中把它复杂化了。非常感谢。

标签: c++


【解决方案1】:

您可以在循环内输入一行并尝试将其转换为整数,因此如果转换失败意味着一个非整数并立即中断循环,返回一个错误,告诉您找到了一个非整数。

否则继续读取直到文件末尾然后检查值是否小于或大于 40 检查循环是否读取所有内容或由于非整数值而中断:

#include <iostream>
#include <string>
#include <fstream>
using namespace std;

enum ERRORFLAG{INIT, LESS_40, MORE_40, NON_INT}; // enumerate error

int main()
{

    ifstream in("data.txt");

    string sLine; // input one line for each read
    int value; // value that will be assigned the return value of conversion
    int count = 0; // counter for integer values
    ERRORFLAG erFlag = INIT; // intialize the error flag

    while(getline(in, sLine)) // iterate reading one line each time
    {
        if( !(value = atoi(sLine.c_str()) ) ) // conversion from string to integer so if the conversion failed else body will be executed
        {
            erFlag = NON_INT; // setting the error flag to non-int and break
            break;
        }
        else
            count++; // otherwise continue reading incrementing count 
    }

    if(INIT == erFlag) // check whether the loop finishes successfully or a non-int caused it to break
    {
        if( count < 40) // checking whether number of ints less than 40
            erFlag = LESS_40; // 
        else
            if(count > 40) // or more than 40
                erFlag = MORE_40;
    }

    // printing the error
    switch(erFlag)
    {
        case LESS_40:
            cout << "Error: less than 40 integers << endl"; 
        break;
        case MORE_40:
            cout << "Error: More than 40 integers << endl"; 
        break;
        case NON_INT:
            cout << "Error: non-intger found!" << endl;
        break;
        default:
            cout << "Undefined Error" << endl;
    }

    in.close();

    std::cout << std::endl;
    return 0;
}

【讨论】:

    【解决方案2】:
    #include <iostream>
    
    using namespace std;
    
    int main() {
        int count = 0;
        int x;
    
        istream& is = cin; // works with every class that inherits this one
    
        while (is >> x) ++count;
    
        if (is.eof()) {} // end of file reached
        else {} // a bad value has been read
    
        cout << "Read count " << count << '\n';
    

    }

    【讨论】:

      【解决方案3】:

      这个程序工作正常:首先读取文件检查非数字和非空白字符,如果发现 break 立即设置错误标志。

      请记住,white spaces like single and tab space 不会被视为无效,因为它们在您的文件中用作separators,因此digitwhite space 以外的任何字符都会中断循环并返回错误。

      如果没有发生错误(未找到无效字符)并到达文件末尾,则再次读取将整数值推入向量的文件,这是一个好主意,不需要计数器,然后检查向量的大小是否小于或者超过40个发出错误,否则打印vector的内容:

      #include <iostream>
      #include <string>
      #include <fstream>
      using namespace std;
      #include <vector>
      
      enum ERRORFLAG{INIT, LESS_40, MORE_40, NON_INT};
      
      int main()
      {
      
          ifstream in("data.txt");
      
          char c;
          string sLine;
          int value;
          vector<int> vec;
          ERRORFLAG erFlag = INIT;
      
          while(in >> c)
          {
              if(!isspace(c) && !isdigit(c))
              {
                  erFlag = NON_INT;
                  break;
              }
          }
      
          in.clear();
          in.seekg(0, ios::beg); // jumping back the the beginning of the file moving the get pointer to the beginning
      
          while(in >> value)
              vec.push_back(value);
      
          if(NON_INT == erFlag)
              cout << "non-int found!" << endl;
          else
          {
              if(vec.size() < 40)
                  cout << "les than 40 integers!" << endl;
              else
                  if(vec.size() > 40)
                      cout << "more than 40 integers found!" << endl;
              else
                  for(int i(0); i < vec.size(); i++)
                      cout << vec[i] << ", ";
          }   
      
          std::cout << std::endl;
          return 0;
      }
      

      【讨论】:

        猜你喜欢
        • 2014-05-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多