LINUX.ORG.RU

[C++] Unexpected behaviour

 


0

0

Поразительно, но программа из учебного курса по информатике (1 курс)
работает как-то странно и неожиданно.

Проблема в том, что на проверке достижения конца файла, программа
уходит в бесконечный цикл.

Проблема наблюдается в: gcc (4.1.2 20070925 (Red Hat 4.1.2-33)),
Borland C++ Builder 6. Отсутствует в BDS...

Непонятно, в чём дело, но я не вижу какой-то явной ошибки.
Код писал не я, но не смог разобраться, так как последний раз что-то
писал на C++ порядка полугода назад.

---8<---
#include <fstream>                //for file streams
#include <iostream>
using namespace std;
class person                      //class of persons
   {
   protected:
      char name[80];              //person's name
      int age;                    //person's age
   public:
      void getData()              //get person's data
         {
         cout << "\n   Enter name: "; cin >> name;
         cout << "   Enter age: "; cin >> age;
         }
      void showData()             //display person's data
         {
         cout << "\n   Name: " << name;
         cout << "\n   Age: " << age;
         }
   };
int main()
   {
   char ch;
   person pers;                   //create person object
   fstream file;                  //create input/output file
                                  //open for append
   file.open("GROUP.DAT", ios::app | ios::out |
                                      ios::in | ios::binary );
   do                             //data from user to file
      {
      cout << "\nEnter person's data:";
      pers.getData();             //get one person's data
                                  //write to file
      file.write( reinterpret_cast<char*>(&pers), sizeof(pers) );
      cout << "Enter another person (y/n)? ";
      cin >> ch;
      }
   while(ch=='y');                //quit on 'n'
   file.seekg(0);                 //reset to start of file
                                   //read first person
   file.read( reinterpret_cast<char*>(&pers), sizeof(pers) );
   while( !file.eof() )           //quit on EOF
      {
      cout << "\nPerson:";        //display person
      pers.showData();            //read another person
      file.read( reinterpret_cast<char*>(&pers), sizeof(pers) );  
      }

   cout << endl;
   getchar();
   return 0;
   }

--->8---

Повторюсь ещё раз, программа уходит в бесконечный цикл по ряду непонятных
причин :(
anonymous

> последний раз что-то писал на C++ порядка полугода назад.

я 3 года назад

Вопрос номер один: ты случайно не пытаешься считать этой программой файл персон записанный программой скомпилированной другим компилятором??

dilmah ★★★★★
()
Ответ на: комментарий от generatorglukoff

хех, спасибо, как-то не подумывал об этом.

сейчас буду ковырять дальше.

eveel ★★
()

не забывай, что еоф бит выставляется только после неудавшейся попытки считывания. Если ты просто считал все байты, то еоф бита еще нет.

dilmah ★★★★★
()
Ответ на: комментарий от dilmah

о, как раз на это натолкнулся, большое спасибо ещё раз

eveel ★★
()
Ответ на: комментарий от generatorglukoff

> 1. Добавляем чудесную строчку (или многострочие) if(!file) { cout << "Error opening file!" << endl; }

Учитывая, что file это объект, то !file не выполнится.

Reset ★★★★★
()
Ответ на: комментарий от Reset

> Учитывая, что file это объект, то !file не выполнится.

читаем про перегруженные операторы и преобразования

dilmah ★★★★★
()

И никому не кажется странным порядок выполнения?

Внчале что то выводим:
pers.showData(); //read another person

И только теперь читаем из файла:
file.read( reinterpret_cast<char*>(&pers), sizeof(pers) );

А вообще, несколько странно хранить в файле класс целиком. Как читать подобные данные на другой архитектуре, или как быть, если программа скомпилена другой версией компилятора?

andreyu ★★★★★
()
Ответ на: комментарий от andreyu

> И никому не кажется странным порядок выполнения?

у него еще один read стоит перед циклом:) Каша-малаша готова:)

dilmah ★★★★★
()

file.read( reinterpret_cast<char*>(&pers), sizeof(pers) );

И казалось бы, причём здесь C++? Если нужно записывать объект в файл, используем готовый сериализатор или пишем свой, если так стоит задача. То, что вы делаете -- самое плохое, что можно придумать вообще. Такие файлы нельзя переносить не только между разными машинами, но и между разными версиями одного компилятора.

А как насчёт конструкторов и всего остального? Вы подумали, что будет вызвано после такого чтения? Как это отразится на внутренних полях, которые компилятор добавил в класс "для себя"?

Более того, посмотрите, *где* находится запись _класса_ в файл? В левой функции за пределами класса! Кто бы мог подумать. Объектно-ориентированные технологии отдыхают! Нужно написать метод класса, который будет принимать поток в качестве параметра и записывать свои данные в этот файл.

using namespace std;

Не делайте больше так, это больно. Вам нужен только cin и cout, а не весь ворох констант, объектов и классов: using std::cin; using std::cout;

anonymous
()
Ответ на: комментарий от alex_custov

>Там переопределён оператор "!"

!file возможно выполнить по другой причине: там переопределён оператор

operator bool()

так же как и в любом потоке STL

ты ведь пишешь иногда

while (std::cin>>a)

{

//...

}

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.