Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Проблема с записью в файл


Автор: Vaz007 3.9.2013, 19:35
Добрый вечер. Есть проблема в записи в файл.
Сначала рабочий вариант:
Groupa - класс состоящий из вектора указателей на студентов
Код

std::vector <Student *> group;


В классе Student есть функция записи в файл (класс Student имеет данные имя , возраст)

Код

        Groupa group;
    Student *p;

    std::ifstream out("E:\student.txt");
    std::ofstream in("E:\writefile.txt");
    
    p = new Student();
    std::cin >>*p;
    
    group.Add(*p);// обычное добавление в вектор
    group.Write(in);// описание функции дано ниже

Запись в файл происходит.

А теперь код ,который мне нужен, не понимаю, почему не работает запись.

Код

    Showmenu();
    char choice;
    std::cin >>choice;
    while(choice!='f' || choice!='F')
    {
        tolower(choice);
        switch(choice)
        {
            case 'a':
                p = new Student();
                std::cin >> *p;
                group.Add(*p);
                break;

            case 'b':
                group.Show();
                break;

            case 'c':
                group.Read(out);// считывание работает
                break;

            case 'd':
                group.Write(in); // эта запись почему-то нет
                
                break;

            case 'e':
                group.Clear();
                break;

            default:
                std::cin.clear();
                std::cin.ignore(256,'\n');
                std::cout <<"Hello from default!!" <<std::endl;

        }
         Showmenu();
         std::cin >>choice;
    }


// методы ,которые я использую для записи в файл

void Groupa::Write(std::ofstream & Filein)
{
    for(int i=0;i<group.size();++i)
        group[i]->WriteFile(Filein);
}

void Student::WriteFile(std::ofstream & inFile)
{
    if(!inFile.is_open())
    {
        std::cout<<"Couldn't open file!!" <<std::endl;
        std::cout <<"Failure!!" <<std::endl;
        exit(0);
    }

    if(inFile.good())
        inFile << name <<"\n" << age <<"\n";
} 


Помогите пожалуйста разобраться.

Автор: feodorv 3.9.2013, 22:12
Цитата(Vaz007 @  3.9.2013,  20:35 Найти цитируемый пост)
    while(choice!='f' || choice!='F')

Хотя бы одно условие обязательно будет выполнено.
Должно быть, имелось в виду
Код

    while(choice!='f' && choice!='F')


Добавлено через 4 минуты и 55 секунд
Цитата(Vaz007 @  3.9.2013,  20:35 Найти цитируемый пост)
        tolower(choice);

А тут, наверное, так:
Код

        choice = tolower(choice);


Добавлено через 8 минут и 19 секунд
Цитата(Vaz007 @  3.9.2013,  20:35 Найти цитируемый пост)
не понимаю, почему не работает запись.

Вы бы выдали отладочную информацию:
Код

            case 'd':
                cout << "Writing into file" << endl;
                group.Write(in);
                break;

А то вдруг до group.Write(in) дело не доходит...

Добавлено через 10 минут и 56 секунд
Цитата(Vaz007 @  3.9.2013,  20:35 Найти цитируемый пост)
    std::ifstream out("E:\student.txt");
    std::ofstream in("E:\writefile.txt");

А здесь нужны двойные слэши:
Код

    std::ifstream out("E:\\student.txt");
    std::ofstream in("E:\\writefile.txt");


Добавлено через 12 минут и 55 секунд
А ещё нужно проверять, что in и out были открыты без ошибок...

Автор: Vaz007 3.9.2013, 22:34
Спасибо за замечания исправил. 
Фото отладки сейчас выложу

Добавлено через 28 секунд
Фото1

Автор: Vaz007 3.9.2013, 22:35
Фото2

Автор: Vaz007 3.9.2013, 22:35
Фото3
Запись не работает все равно.

Автор: akizelokro 4.9.2013, 01:25
Проверь значение "age" и строчку

Код

std::cin >> *p;

Автор: feodorv 4.9.2013, 09:41
Цитата(Vaz007 @  3.9.2013,  23:35 Найти цитируемый пост)
Запись не работает все равно.

Всё-таки продублируйте выдачу на экран:
Код

void Student::WriteFile( std::ofstream & inFile )
{
  ...
  if( inFile.good() )
  {
    std::cout << name << "\n" << age << "\n";
    inFile << name << "\n" << age << "\n";
  }
}



Цитата(Vaz007 @  3.9.2013,  23:35 Найти цитируемый пост)
Запись не работает все равно.

В чём конкретно это выражается? Файла нет? Файл создаётся, но он пустой? Двойные слэши поправили?

Автор: Vaz007 4.9.2013, 12:43
файл создается , но он пустой. слэши поправил

Автор: akizelokro 4.9.2013, 13:24
flush сделай перед закрытием файла

и что у тебя там пишется в класс в этой строчке? ты для класса Sudent перегрузку оператора ">>" делал?
Если нет, то всё что угодно может записаться.  Например, name будет нормальным по значению, а вот age - непонятно что.

Автор: Vaz007 4.9.2013, 18:21
после flush заработал ))) только объясните почему??

Автор: akizelokro 4.9.2013, 19:57
Цитата(Vaz007 @  4.9.2013,  18:21 Найти цитируемый пост)
после flush заработал ))) только объясните почему?? 


На этом часто при изучении материала накалываются.
Используется буфферизация ввода-вывода, при записи в файл нужно "сбросить" содержимое буфера записи на жёсткий диск в файл перед завершением работы.

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

Автор: Vaz007 4.9.2013, 21:06
akizelokro, огромное спасибо))

Автор: SenkraD 5.9.2013, 11:02
ну вообще-то стримы в деструкторах вызывают flush и close (не во всех реализациях явно, могут через свои буферы этто делать), так что скорее всего если смотреть сразу после прохождения строки в режиме трасировки, то файл мог не обновляться, но по выходу с области видимости стримового обьекта, он ДОЛЖЕН был записываться и обновляться

Автор: xvr 5.9.2013, 13:45
Цитата(akizelokro @  4.9.2013,  19:57 Найти цитируемый пост)
Почему это не делается автоматически, я тебе не скажу.

Подозреваю, что программе нормально завершиться не дают. Например она слетает по исключению или ее банально прибивают по Ctrl-C  smile 

Автор: akizelokro 5.9.2013, 14:38
Цитата

Подозреваю, что программе нормально завершиться не дают. Например она слетает по исключению или ее банально прибивают по Ctrl-C  smile 


Я текста программы не вижу. Я прочитал, что поток ввода открывается в функции и должен закрываться, предположу, в функции.
Автоматически синхронизация буфера вывода осуществляется в 4 случаях:
<< endl;

<< flush;

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

Здесь случай достаточно нестандартный. Пишут не '\n', а std::endl в подавляющем большинстве случаев и также в подавляющем большинстве случаев рассматриваются программы для начинающих в консольном режиме, где потоки открываются в main и с ним же закрываются.

Добавлено через 10 минут и 50 секунд
Щас глянул полседнюю прогу. Оказалось, что я у себя везде flush'у перед close.
Но я не особо лихой программист. Правда, у меня и проблем что чего-то не записалось, не бывает никахда. smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)