2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




На страницу 1, 2  След.
 
 Некорректное завершение программы
Сообщение14.03.2016, 23:49 
Аватара пользователя
пишу программу для записи объектов в файл с перегрузкой операторов >> & <<

код: [ скачать ] [ спрятать ]
Используется синтаксис C++
#include<iostream>
#include<fstream>
#include<cstring>
using namespace std;
////////////////////////////////////////////////////////////
class employee{
        private:
                string name;
                unsigned long ID;
        public:
                employee():name(""),ID(0){}
                void putdata(){cout<<"Enter employee's name: ";cin>>name;cout<<"Enter employee's ID: ";cin>>ID;}
                void getdata(){cout<<"Employee's name is: "<<name<<endl;cout<<"Employee's ID is: "<<ID<<endl;}
                friend ostream& operator << (ostream&,employee&);
                friend istream& operator >> (istream&,employee&);
};

ostream& operator << (ostream& f,employee& emp){ // запись объекта в файл
        f<<emp.ID<<"-"<<emp.name<<"/";
        return f;
}

istream& operator >> (istream& f,employee& empl){ // чтение объекта из файла
        char dummy;
        f>>empl.ID>>dummy;
        f>>dummy;
        empl.name="";
        while(dummy!='/'){
                empl.name+=dummy;
                f>>dummy;              
        }
}
////////////////////////////////////////////////////////////
int main(){
        char ch='y';
        fstream file;
        file.open("TAB.txt");
        employee one;
        while(ch=='y'){ // цикл для записи
                one.putdata();
                file<<one; // write data into file
                cout<<"Go on?(y,n): ";cin>>ch;
        }
//      file.seekg(0);
        while(!file.eof()){ // цикл для чтения из файла
                file>>one;
                one.getdata();
        }
        file.close();
        system("pause");
        return 0;
}
 


после ввода объектов программа зависает, подскажите пожалуйста в чём дело?

 
 
 
 Re: Некорректное завершение программы
Сообщение15.03.2016, 01:11 
1. Закомментированный вызов file.seekg(0) означает, что вы читаете за концом файла. При этом file.eof() не возвращает истину, чтобы он вернул истину надо сделать одно неудачное чтение а его у вас нет.

2. Когда вы что-то написали в файл, и собираетесь это же прочитать, вам надо сбросить буфера:
http://stackoverflow.com/questions/1753 ... me-fstream

3. Я бы так делать не стал. Я бы открыл файл на запись, записал, закрыл, открыл на чтение, прочитал, закрыл. В этом случае нет всех этих скользких мест. RW операции с файлами - сложное место, форматный ввод/вывод тоже. Зря вы собрали их вместе.

 
 
 
 Re: Некорректное завершение программы
Сообщение15.03.2016, 10:49 
Аватара пользователя
Сделал 2 потока: запись и чтение

код: [ скачать ] [ спрятать ]
Используется синтаксис C++
#include<iostream>
#include<fstream>
#include<cstring>
using namespace std;
////////////////////////////////////////////////////////////
class employee{
        private:
                string name;
                unsigned long ID;
        public:
                employee():name(""),ID(0){}
                void putdata(){cout<<"Enter employee's name: ";cin>>name;cout<<"Enter employee's ID: ";cin>>ID;}
                void getdata(){cout<<"Employee's name is: "<<name<<endl;cout<<"Employee's ID is: "<<ID<<endl;}
                friend ostream& operator << (ostream&,employee&);
                friend istream& operator >> (istream&,employee&);
};

ostream& operator << (ostream& f,employee& emp){ // запись объекта в файл
        f<<emp.ID<<"-"<<emp.name<<"/";
        return f;
}

istream& operator >> (istream& f,employee& empl){ // чтение объекта из файла
        char dummy;
        f>>empl.ID>>dummy;
        f>>dummy;
        empl.name="";
        while(dummy!='/'){
                empl.name+=dummy;
                f>>dummy;              
        }
}
////////////////////////////////////////////////////////////
int main(){
        char ch='y';
        ofstream file1;
        ifstream file2;
        file1.open("TAB.txt");
        employee one;
        while(ch=='y'){ // цикл для записи
                one.putdata();
                file1<<one; // write data into file
                file1.flush();
                cout<<"Go on?(y,n): ";cin>>ch;
        }
        file1.close();
        file2.open("TAB.txt");
        while(file2){ // цикл для чтения из файла
                file2>>one;
                one.getdata();
        }
        file2.close();
        system("pause");
        return 0;
}
 


Теперь стало зависать после вывода данных

-- 15.03.2016, 11:04 --

Поставил цикл for и всё норм:

код: [ скачать ] [ спрятать ]
Используется синтаксис C++
#include<iostream>
#include<fstream>
#include<cstring>
using namespace std;
////////////////////////////////////////////////////////////
class employee{
        private:
                string name;
                unsigned long ID;
        public:
                employee():name(""),ID(0){}
                void putdata(){cout<<"Enter employee's name: ";cin>>name;cout<<"Enter employee's ID: ";cin>>ID;}
                void getdata(){cout<<"Employee's name is: "<<name<<endl;cout<<"Employee's ID is: "<<ID<<endl;}
                friend ostream& operator << (ostream&,employee&);
                friend istream& operator >> (istream&,employee&);
};

ostream& operator << (ostream& f,employee& emp){ // запись объекта в файл
        f<<emp.ID<<"-"<<emp.name<<"?";
        return f;
}

istream& operator >> (istream& f,employee& empl){ // чтение объекта из файла
        char dummy;
        f>>empl.ID>>dummy;
        f>>dummy;
        empl.name="";
        while(dummy!='?'){
                empl.name+=dummy;
                f>>dummy;              
        }
}
////////////////////////////////////////////////////////////
int main(){
        char ch='y';
        ofstream file1;
        ifstream file2;
        file1.open("TAB.txt");
        employee one;
        while(ch=='y'){ // цикл для записи
                one.putdata();
                file1<<one; // write data into file
                cout<<"Go on?(y,n): ";cin>>ch;
        }
        file1.close();
        file2.open("TAB.txt");
//      while(file2){ // цикл для чтения из файла
//              file2>>one;
//              one.getdata();
//      }
        for(int i=0;i<1;i++){
                file2>>one;
                one.getdata();
        }
        file2.close();
        system("pause");
        return 0;
}
 


То есть какая-то ошибка с условием while(file2). В Лафоре написано, что file2 возвращает указатель на объект, который даст true, если нет ошибок и даст 0, если есть ошибка, например конец файла. Можете прокомментировать?

 
 
 
 Re: Некорректное завершение программы
Сообщение15.03.2016, 11:20 
Ваш оператор ввода зацикливается при чтении за концом файла. Вам следует проверять конец файла после каждого вызова >>.

Вот здесь есть обсуждение: http://stackoverflow.com/questions/4533 ... s-eof-work

 
 
 
 Re: Некорректное завершение программы
Сообщение16.03.2016, 15:52 
Аватара пользователя
Из данной ссылки я понял, что предлагают выводить посимвольно file2.get(), разве нет способа нормально объекты вывести?

 
 
 
 Re: Некорректное завершение программы
Сообщение16.03.2016, 16:04 
Я уточню что имелось ввиду. Если оператор >> не может ввести данные, то переводит поток в "нехорошее" (отсылка к методу good) состояние (в вашем случае eof). Все последующие вызовы >> ничего не делают. Ваш оператор ввода ломается на первом вызове >>. Переменная dummy остаётся не инициализированной. Цикл становится бесконечным.

Чтобы исправить ситуацию, вам нужно проверять "хорошесть" потока в процессе чтения объекта. Об этом написано в первом ответе по ссылке.

 
 
 
 Re: Некорректное завершение программы
Сообщение17.03.2016, 12:19 
Аватара пользователя
Работает:

код: [ скачать ] [ спрятать ]
Используется синтаксис C++
#include<iostream>
#include<fstream>
#include<cstring>
using namespace std;
////////////////////////////////////////////////////////////
class employee{
        private:
                string name;
                unsigned long ID;
        public:
                employee():name(""),ID(0){}
                void putdata(){cout<<"Enter employee's name: ";cin>>name;cout<<"Enter employee's ID: ";cin>>ID;}
                void getdata(){cout<<"Employee's name is: "<<name<<endl;cout<<"Employee's ID is: "<<ID<<endl;}
                friend ostream& operator << (ostream&,employee&);
                friend istream& operator >> (istream&,employee&);
};

ostream& operator << (ostream& f,employee& emp){ // write into a file
        f<<emp.ID<<"-"<<emp.name<<"?";
        return f;
}

istream& operator >> (istream& f,employee& empl){ // read from a file
        char dummy;
        employee tmp;
        if(f>>tmp.ID>>dummy&&dummy=='-'){
                while(f>>dummy&&dummy!='?')
                        tmp.name+=dummy;
                if(f)swap(tmp,empl);
        }
        return f;                              
}
////////////////////////////////////////////////////////////
int main(){
        char ch='y';
        ofstream file1;
        ifstream file2;
        file1.open("TAB.txt");
        employee one;
        while(ch=='y'){ // writing in cycle
                one.putdata();
                file1<<one; // write data into file
                cout<<"Go on?(y,n): "<<endl;cin>>ch;
        }
        file1.close();
        file2.open("TAB.txt");
        while(file2>>one) // reading cycle
                one.getdata();         
        file2.close();
        system("pause");
        return 0;
}

 
 
 
 Re: Некорректное завершение программы
Сообщение17.03.2016, 12:33 
Хорошо. Решение корректное. Мне нравится что ваш оператор ввода исполняет подразумеваемый контракт.
Теперь можно полировать, если хотите. Эта функция вводит последовательность символов до разделителя (http://www.cplusplus.com/reference/stri ... g/getline/):
Код:
istream& getline (istream& is, string& str, char delim);
Если вы её задействуете, то вы снизите нагрузку на поток (посимвольное чтение работает медленно), уменьшите фрагментацию памяти (избавитесь от кучи промежуточных строк), уменьшите сложность с квадратичной до линейной (заметно только для длинных строк).

 
 
 
 Re: Некорректное завершение программы
Сообщение17.03.2016, 23:32 
Аватара пользователя
Как-то так:

код: [ скачать ] [ спрятать ]
Используется синтаксис C++
#include<iostream>
#include<fstream>
#include<cstring>
using namespace std;
////////////////////////////////////////////////////////////
class employee{
        private:
                string name;
                unsigned long ID;
        public:
                employee():name(""),ID(0){}
                void putdata(){cout<<"Enter employee's name: ";cin>>name;cout<<"Enter employee's ID: ";cin>>ID;}
                void getdata(){cout<<"Employee's name is: "<<name<<endl;cout<<"Employee's ID is: "<<ID<<endl;}
                friend ostream& operator << (ostream&,employee&);
                friend istream& operator >> (istream&,employee&);
};

ostream& operator << (ostream& f,employee& emp){ // write into a file
        f<<emp.ID<<"-"<<emp.name<<"?";
        return f;
}

istream& operator >> (istream& f,employee& empl){ // read from a file
        char dummy;
        employee tmp;
        if(f>>tmp.ID>>dummy&&dummy=='-'){
                if(getline(f,tmp.name,'?'))             //f>>dummy&&dummy!='?'
                                                                                //tmp.name+=dummy;
                if(f)swap(tmp,empl);
        }
        return f;                              
}
////////////////////////////////////////////////////////////
int main(){
        char ch='y';
        ofstream file1;
        ifstream file2;
        file1.open("TAB.txt");
        employee one;
        while(ch=='y'){ // writing in cycle
                one.putdata();
                file1<<one; // write data into file
                cout<<"Go on?(y,n): "<<endl;cin>>ch;
        }
        file1.close();
        file2.open("TAB.txt");
        while(file2>>one) // reading cycle
                one.getdata();         
        file2.close();
        system("pause");
        return 0;
}

 
 
 
 Re: Некорректное завершение программы
Сообщение17.03.2016, 23:46 
Почти идеально. Но есть вариант входного потока, когда оператор ввода не исполняет свой контракт. Хотя в вашей программе это почти не возможно.

 
 
 
 Re: Некорректное завершение программы
Сообщение18.03.2016, 09:09 
Аватара пользователя
Интересно, приведите пример пожалуйста

 
 
 
 Re: Некорректное завершение программы
Сообщение18.03.2016, 09:23 
Если оператор >> не может прочитать из потока, он должен перевести поток в "нехорошее" состояние. В вашем случае ввод из потока данных виде "1+" приведёт простому пропуску двух символов и незаполненному объекту, а окружающий код ничего не поймёт, так как поток останется в хорошем состоянии.

 
 
 
 Re: Некорректное завершение программы
Сообщение24.03.2016, 11:14 
Аватара пользователя
Добавил проверку:

код: [ скачать ] [ спрятать ]
Используется синтаксис C++
#include<iostream>
#include<fstream>
#include<cstring>
#include<cstdlib>
using namespace std;
////////////////////////////////////////////////////////////
class employee{
        private:
                string name;
                unsigned long ID;
        public:
                employee():name(""),ID(0){}
                void putdata(){cout<<"Enter employee's name: ";cin>>name;cout<<"Enter employee's ID: ";cin>>ID;}
                void getdata(){cout<<"Employee's name is: "<<name<<endl;cout<<"Employee's ID is: "<<ID<<endl;}
                friend ostream& operator << (ostream&,employee&);
                friend istream& operator >> (istream&,employee&);
};

ostream& operator << (ostream& f,employee& emp){ // write into a file
        if(!(f<<emp.ID)){
                cout<<"Wrong ID, try again..."<<endl;
                exit(1);
                }
                else
                        f<<'-';
        return f;
}

istream& operator >> (istream& f,employee& empl){ // read from a file
        char dummy;
        employee tmp;
        if(f>>tmp.ID>>dummy&&dummy=='-'){                                              
                if(getline(f,tmp.name,'?'))             //f>>dummy&&dummy!='?'
                                                                                //tmp.name+=dummy;
                if(f)swap(tmp,empl);
        }
        return f;                              
}
////////////////////////////////////////////////////////////
int main(){
        char ch='y';
        ofstream file1;
        ifstream file2;
        file1.open("TAB.txt");
        employee one;
        while(ch=='y'){ // writing in cycle
                one.putdata();
                file1<<one; // write data into file
                cout<<"Go on?(y,n): "<<endl;cin>>ch;
        }
        file1.close();
        file2.open("TAB.txt");
        while(file2>>one) // reading cycle
                one.getdata();          
        file2.close();
        system("pause");
        return 0;
}

 
 
 
 Re: Некорректное завершение программы
Сообщение24.03.2016, 13:07 
Не туда добавили. И реакция на ошибку чрезмерная.

 
 
 
 Re: Некорректное завершение программы
Сообщение27.03.2016, 11:17 
Аватара пользователя
Изменил реакцию на ошибку ввода ID и добавил изменение флага при некорректном выводе из потока

код: [ скачать ] [ спрятать ]
Используется синтаксис C++
#include<iostream>
#include<fstream>
#include<cstring>
using namespace std;
////////////////////////////////////////////////////////////
class employee{
        private:
                string name;
                unsigned long ID;
        public:
                employee():name(""),ID(0){}
                void putdata(){cout<<"Enter employee's name: ";cin>>name;cout<<"Enter employee's ID: ";cin>>ID;}
                void getdata(){cout<<"Employee's name is: "<<name<<endl;cout<<"Employee's ID is: "<<ID<<endl;}
                friend ostream& operator << (ostream&,employee&);
                friend istream& operator >> (istream&,employee&);
};

ostream& operator << (ostream& f,employee& emp){ // write into a file
        if(!(f<<emp.ID)){
                cout<<"Wrong ID, try again..."<<endl;
                f.clear();
                }
                else
                        f<<'-';
        return f;
}

istream& operator >> (istream& f,employee& empl){ // read from a file
        char dummy;
        employee tmp;
        if(f>>tmp.ID>>dummy&&dummy=='-'){                                              
                if(getline(f,tmp.name,'?'))             //f>>dummy&&dummy!='?'
                                                                                //tmp.name+=dummy;
                if(f)swap(tmp,empl);
        else{
                f.setstate(ios_base::badbit);
                cout<<"Unable to read a file...";
                }              
    }
    return f;                              
}
////////////////////////////////////////////////////////////
int main(){
        char ch='y';
        ofstream file1;
        ifstream file2;
        file1.open("TAB.txt");
        employee one;
        while(ch=='y'){ // writing in cycle
                one.putdata();
                file1<<one; // write data into file
                cout<<"Go on?(y,n): "<<endl;cin>>ch;
        }
        file1.close();
        file2.open("TAB.txt");
        while(file2>>one) // reading cycle
                one.getdata();          
        file2.close();
        system("pause");
        return 0;
}
 

 
 
 [ Сообщений: 16 ]  На страницу 1, 2  След.


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group