user4815708
user4815708

Reputation:

Error handling when reading integers from a file

Sorry for the somewhat beginner question, but I've been at this for a couple of days and can't figure out a solution.

I'm basically reading integers from a file, these files should have a set amount of numbers, for the purpose of this question let us say 40. I can return an error fine when the file has less than or more than 40 integers. However, if there happens to be a non-numeric character in there, I'm struggling to figure out how to return an error. This is what I'm currently doing:

int number = 0;
int counter = 0;

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

if (counter < 40)
  return error;

It is at this point I'm a bit confused where to go. My while loop will terminate when the input stream is not an int, but there are two cases when this could happen, a non-integer character is in there, or the end of file has been reached. If we're at eof, my error message is fine and there were less than 40 integers. However, we could also be at less than 40 if it encountered a non-int somewhere. I want to be able to determine the difference between the two but struggling to figure out how to do this. Any help would be appreciated. Thanks!

Upvotes: 2

Views: 1378

Answers (3)

Raindrop7
Raindrop7

Reputation: 3911

this program works fine: first read the file checking for a non-digits and non-white space characters and if you find break immediately setting the error flag.

keep in mind that white spaces like single and tab space will not be considered as invalid because they are used in your file as separators so any character other than digit or white space will break the loop returning an error.

if no error occurred (no invalid character found) and reaching the end of file then read again the file pushing the integer values into a vector which is a good idea without needing a counter then check the size of vector if it is less or more than 40 issuing an error otherwise print the content of 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;
}

Upvotes: 0

zeralight
zeralight

Reputation: 710

#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';

}

Upvotes: 0

Raindrop7
Raindrop7

Reputation: 3911

you can input a line inside loop and try to convert it to integer so if the conversion fails means a non-integer and immediately break the loop returning a error telling that a non-integer found.

otherwise continue read until the end of file then check whether values are less or more 40 checking whether the loop reads all the content or broke because of non-integer value:

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

Upvotes: 1

Related Questions