Как игнорировать плохие данные при чтении из файла в C ++? - PullRequest
1 голос
/ 09 марта 2011

Чтобы быть более точным, мне дают следующие данные:

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

Буквы обозначают день недели, а цифры обозначают время (в военное время) и продолжительность разговора (в минутах).,

Код работает отлично, пока вводятся правильные данные, но, как и в этом случае, когда вводится Sq, цикл прерывается.пока моя логика

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 - мой файловый объект, c1 и c2 имеют тип char, а функция 'checker' проверяет символы, чтобы увидеть, является ли комбинация 2 действительным днемнеделя.Если нет, то возвращается 0.

из того, что я понимаю instream.ignore с этими параметрами пропустит не более 100 символов или пока не будет найдена новая строка.Проблема в том, что после выполнения этого оператора цикл завершается.У меня также может быть несколько случайных кутов или аутсайтов, я просто проверял материал.

вот полный код на случай, если я пропущу что-то важное:

#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: спасибоответы, я согласен на 100%, что я должен читать это как строку и анализировать строку, но я в настоящее время беру необходимый класс программирования, и хотя у меня было буквально 100% материала до того, у меня все это было в Java, такЯ не очень хорошо разбираюсь в синтаксисе, и нам говорят, что мы можем использовать только функции / циклы / методы, которые обсуждались в лекции (я полагаю, чтобы предотвратить обман).Кроме того, '\ n' вместо '/ n' очень помогло, хаха, спасибо!

Кроме того, первое, что я поймал, была ошибка двух плохих дней подряд .. Я изменил ее на управляемую структуру if / elseвозвращением 0 из 'checker', чтобы поймать все плохие дни.

в заключение ... этот сайт заставляет меня хихикать, как школьница ... сообщество программистов, которые намного лучше меняпомогаю о

Ответы [ 4 ]

2 голосов
/ 09 марта 2011

Вместо этого используйте cin.getline, чтобы получить всю строку в виде строки, а затем проанализировать строку.

2 голосов
/ 09 марта 2011

Причиной прерывания вашего цикла является следующий оператор:

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

Это означает, что «игнорировать 100 символов или / n в зависимости от того, что произойдет раньше»,Поэтому, когда ваша программа пропускает 100 символов, она достигает конца файла, и ваш цикл прерывается при достижении eof ().Также вы используете неправильный символ для LINE END.Это не "/ N".Это "\ n" (обратная косая черта), и чтобы представить его в коде C, вы должны написать "\ n".

Но ваш алгоритм требует значительных улучшений.Попробуйте прочитать полную строку, а затем проверьте правильность первых двух символов в этой строке.В противном случае игнорируйте эту строку.Также в вас есть функция проверки.Было бы лучше, если бы вы преобразовали оба символа в верхний регистр, а затем проверили, действительны ли они, чтобы вам не приходилось проверять все комбинации.Когда вы применяете функцию toupper () к «mo», «Mo», «mO» или «MO», результатом будет MO во всех случаях, а затем вы можете сравнить его только за 1 проверку.

0 голосов
/ 10 марта 2011

Почему бы вам просто не обернуть его в блок "try / catch"?

0 голосов
/ 09 марта 2011

Одна из основных проблем с вашей логикой заключается в том, что, если ввести два плохих дня подряд, что произойдет?

Я бы предложил использовать игнорирование, а затем continue, чтобы повторить цикл (вместо чтения даты ипродолжая вслепую).

...