tim
tim

Reputation: 11

How do i ignore bad data when reading from a file in c++?

To be more specific, I am given this input:

Mo  17 30   15  
Sa  9 00    30  
Tu  3 30    45  
Sq    
Fr  21 01   60

The letters represent a day of the week and the numbers denote time (in military time) and length of the call (in minutes).

The code works perfectly as long as valid data is entered, but, like in this case, when Sq is entered the loop breaks down. heres my logic so far

while(!instream.eof()){

        instream>>c1>>c2;
        day = checker(c1, c2);
        cout<<c1<<" "<<c2<<endl;

    if(day == 0){
        instream.ignore(100,'/n');
        instream>>c1>>c2;
        day = checker(c1, c2);
    }

instream is my file object, c1 and c2 are of type char, and the function checker checks the chars to see if the combination of the 2 is a valid day of the week. If not, it returns 0.

From what I understand, instream.ignore with those arguments will skip at most 100 characters, or until a new line is found. The problem is, after this statement runs, the loop terminates. I also might have some random couts or outstreams in there, I was just checking stuff.

Here is the full code:

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

int checker(char a, char b);
void main(){
    ifstream instream;
    ofstream outstream;

    instream.open("infile.txt");
    outstream.open("outfile.txt");

    double cost = 0, realtime;
        int check = 0, day = 0, hour, min, time, i = 1;
    char c1, c2, c3;

    while(!instream.eof()){

        instream>>c1>>c2;
        day = checker(c1, c2);
        cout<<c1<<" "<<c2<<endl;

    if(day == 0){
        instream.ignore(100,'/n');
        instream>>c1>>c2;
        day = checker(c1, c2);
        }
    instream>>hour>>min>>time;
    realtime = 1.0*hour + min/60.0;

    if(day == 1 && (realtime < 7 || realtime > 21)){
        cost = 0.15 * time;
        outstream<<"The cost of call " << i << " is $" << cost <<endl;
        i++;
    }
    else if(day == 1 && (realtime >= 7 || realtime <= 21)){
        cost = 0.30 * time;
        outstream<<"The cost of call " << i << " is $" << cost <<endl;
        i++;
    }
    else if(day == 2){
        cost = 0.10 * time;
        outstream<<"The cost of call " << i << " is $" << cost <<endl;
        i++;
    }
    outstream<<" "<<hour<<endl;
        outstream<<" "<<min<<endl;
    outstream<<" "<<time<<endl;
    outstream<<" "<<i<<endl;
    }
    cout<<"The program has completed its task"<<endl;
    instream.close();
    outstream.close();
    
}
int checker(char a, char b){
    int day2 = 0;
    if(a == 'M' && b == 'o' || a == 'm'&& b == 'O' || a == 'm'&& b == 'o' || a == 'M'&& b == 'O'){
    day2 = 1;
    }
     
    else if(a == 'T'&& b == 'u' || a == 't'&& b == 'U' || a == 't'&& b == 'u' || a == 'T'&& b == 'u'){
    day2 = 1;
    }
     
    else if(a == 'W'&& b == 'e' || a == 'w'&& b == 'E' || a == 'w'&& b == 'e' || a == 'W'&& b == 'E'){
    day2 = 1;
    }
     
    else if(a == 'T'&& b == 'h' || a == 't'&& b == 'H' || a == 't'&& b == 'h' || a == 'T'&& b == 'H'){
    day2 = 1;
    }
     
    else if(a == 'F'&& b == 'r' || a == 'f'&& b == 'R' || a == 'f'&& b == 'r' || a == 'F'&& b == 'R'){
    day2 = 1;
    }
     
    else if((a == 'S'&& b == 'a') || (a == 's'&& b == 'A') || (a == 's'&& b == 'a') || (a == 'S'&& b == 'A')){
    day2 = 2;
    }
    else if((a == 'S'&& b == 'u') || (a == 's'&& b == 'U') || (a == 's'&& b == 'u') || (a == 'S'&& b == 'U')){
    day2 = 2;
    }
    else
    day2 = 0;

    return day2;
}

--939345676

Edit: I agree 100% that I should be reading it as a line and parsing the string, but I'm currently taking a programming class, and we are told we can only use functions/loops/methods that have been discussed in lectures.

Upvotes: 1

Views: 2030

Answers (4)

Benedikt Bergenthal
Benedikt Bergenthal

Reputation: 505

Why don't you just wrap it up in a "try/catch" block?

Upvotes: -1

Tayyab
Tayyab

Reputation: 10631

The reason that your loop breaks is this statement,

instream.ignore(100,'/n');

This means "Ignore 100 chars or /n whichever comes first". So when your program skips 100 chars it reaches end of file and your loop breaks as eof() is reached. Also you are using wrong char for LINE END. Its not "/n". It is "\n" (back slash), and to represent it in C code you have to write "\n".

But your algorithm needs considerable improvements. Try reading complete line and then check if the first two chars in that line are valid. Otherwise ignore that line. Also in you checker function. It would be better if you convert both chars to upper case and then check if they are valid, so that you don't have to check all combination. when you apply toupper() function to "mo" or "Mo" or "mO" or "MO", the result will be MO in all cases and then you can compare it in 1 check only.

Upvotes: 2

CariElf
CariElf

Reputation: 204

Use cin.getline instead to get the entire line as a string, and then parse the string.

Upvotes: 2

Yann Ramin
Yann Ramin

Reputation: 33167

One major problem with your logic is that if two consecutive bad days are entered, what happens?

I would suggest using ignore, then using continue to retry your loop (instead of reading the date and continuing blindly).

Upvotes: 0

Related Questions