Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Lensato
49 / 49 / 31
Регистрация: 07.10.2015
Сообщений: 170
#1

Когда и как срабатывает eof() ? - C++

15.10.2015, 17:32. Просмотров 559. Ответов 8
Метки нет (Все метки)

Программа:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <Windows.h>
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
 
 
using std::cout;
using std::cin;
using std::endl;
 
const char *data_file = "test1.txt";
 
class Board
{
 
};
 
int main()
{ 
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
 
    int i = 48;
    float f = 32.5234;
 
    std::fstream infile;// (data_file);
    infile.open(data_file, std::ios::in | std::ios::out);
 
    char ch;
    while (!infile.eof())
    {
        infile.get(ch);
        cout << ch;
    }
 
    infile.close();                                                        // эти строки я комментирую и 
    infile.open(data_file, std::ios::in | std::ios::out);  // получается ошибка
 
    infile.seekg(0, std::ios::end);
    cout << endl<< std::setw(10) << "good: " << infile.good() << endl
        << std::setw(10) << "eof: " << infile.eof() << endl
        << std::setw(10) << "fail: " << infile.fail() << endl
        << std::setw(10) << "bad: " << infile.bad() << endl << endl;
 
    infile << endl << "some new string";
 
    cout << endl;
 
    system("pause");
    return 0;
}


Есть файл "test1.txt".
Вся информация в нем это один символ: "1".

Если считывать так:
C++
1
2
3
4
5
while (!infile.eof())
    {
        infile.get(ch);
        cout << ch;
    }
то выводит: 11
Откуда второй символ?
Все что приходит на ум: первый раз он считывает ch, второй раз считывает eof и не присваивает его переменной ch, соответственно ch выводится 2-й раз и цикл наконец заканчивается.

Далее, если закомментировать эти строки:
C++
1
2
infile.close();                                                    // эти строки я комментирую и 
infile.open(data_file, std::ios::in | std::ios::out);  // получается ошибка
то, срабатывает флаг fail()
Почему надо обязательно закрыть уже открытый поток, открыть его еще раз, и только затем будет разрешено установить указатель на нужную позицию в файле?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.10.2015, 17:32
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Когда и как срабатывает eof() ? (C++):

Почему не срабатывает EOF
У меня стоит Visual Studio 2010 написал простенькую программу #include...

Не срабатывает условие while (!file.eof()
Есть функция, которая считает из файла числа в динамический массив: int*...

как поставить EOF?
Ребят, подскажите пожалуйста. Итак, вот листинг программы. Если я открываю...

Как ввести EOF с клавиатуры?
как ввести EOF c клавиатуры ?

Как детектировать EOF с fgets/gets
Проблема в определении: Файл1: строка1 строка2 EOF Файл2: строка1...

std::cin, eof не всегда принимается как признак конца файла
std::string text; char ch = 0; while(!std::cin.get(ch).eof()){...

8
nmcf
6243 / 5555 / 2526
Регистрация: 14.04.2014
Сообщений: 23,355
15.10.2015, 17:36 #2
Лучший ответ Сообщение было отмечено Lensato как решение

Решение

eof устанавливается только при первом неудачном чтении.
C++
1
2
3
4
5
6
while (true)
    {
        infile.get(ch);
        if (infile.eof()) break;
        cout << ch;
    }
0
Lensato
49 / 49 / 31
Регистрация: 07.10.2015
Сообщений: 170
15.10.2015, 17:39  [ТС] #3
Вообще цель была считать файл до его конца и вставить в его конец строку:
C++
1
2
3
4
5
6
7
8
char ch;
    while (!infile.eof())
    {
        infile.get(ch);
        cout << ch;
    }
 
    infile << endl << "some new string";
Цель достигнута, но по-моему криво.
0
nmcf
6243 / 5555 / 2526
Регистрация: 14.04.2014
Сообщений: 23,355
15.10.2015, 17:40 #4
Если достигнут конец, нужно сбросить флаги и переместить указатель в начало, прежде чем повторно читать.
C++
1
2
    infile.clear();
    infile.seekg(0);
0
Lensato
49 / 49 / 31
Регистрация: 07.10.2015
Сообщений: 170
15.10.2015, 17:41  [ТС] #5
Цитата Сообщение от nmcf Посмотреть сообщение
eof устанавливается только при первом неудачном чтении.
Ок, а что на счет установки указателя но новую позицию.
При первой же неудачной попытке считать из файла, дальнейшие манипуляции с ним блокируются?
0
nmcf
6243 / 5555 / 2526
Регистрация: 14.04.2014
Сообщений: 23,355
15.10.2015, 17:42 #6
Лучший ответ Сообщение было отмечено Lensato как решение

Решение

Блокируются, пока не сбросишь флаги - clear().
Зачем тогда гонять эти символы? Сразу после открытия переходи в конец и записывай.
0
Lensato
49 / 49 / 31
Регистрация: 07.10.2015
Сообщений: 170
15.10.2015, 17:44  [ТС] #7
Цитата Сообщение от nmcf Посмотреть сообщение
Зачем тогда гонять эти символы? Сразу после открытия переходи в конец и записывай.
Да мне понять как это вообще работает.
Так то мне не надо в файл ничего писать. Он вообще для чтения.
Спасибо.
0
nmcf
6243 / 5555 / 2526
Регистрация: 14.04.2014
Сообщений: 23,355
15.10.2015, 17:45 #8
Перемещение указателя записи - seekp().
0
Lensato
49 / 49 / 31
Регистрация: 07.10.2015
Сообщений: 170
15.10.2015, 17:49  [ТС] #9
Цитата Сообщение от nmcf Посмотреть сообщение
Перемещение указателя записи - seekp().
Поздно, у меня уже прекрасно работает infile.seekg(0);
Наверное из-за std::ios::in | std::ios::out. Поэкспериментирую...
0
15.10.2015, 17:49
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.10.2015, 17:49
Привет! Вот еще темы с решениями:

Прочитать символы из файла, используя eof() (программа работает не так, как ожидается)
Здравствуйте, мне нужно прочитать символы из файла(желательно с пробелами)....

Когда стоит использовать класс, а когда лучше обойтись без них?
Когда стоит использовать класс, а когда лучше обойтись без них? Когда следует...

Когда надо использовать списки инициализации, а когда можно заменить их констуктором по умолчанию?
1)Любезные,скажите когда надо исп. списки инициализации, а когда можно заменить...

Когда нужно использовать &ссылки ,а когда *указатели?
Желательно с примерами


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru