С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/55: Рейтинг темы: голосов - 55, средняя оценка - 4.75
26 / 26 / 15
Регистрация: 30.12.2015
Сообщений: 95

Различия ifstream::get() и ifstream::get(ch)

03.03.2016, 01:26. Показов 10975. Ответов 7
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток. Была тут тема, в которой я не разобрался до конца. Код ниже проверяет баланс скобок в текстовом файле
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include "StdAfx.h"
 
using namespace std;
 
int main(void)
{
    setlocale(LC_ALL, "Russian");
 
    ifstream in("cppcode.txt");
    ofstream out("scanresult.txt");
 
    if (in.is_open() && out.is_open())
    {
        int symbols[] = { 0, 0, 0, 0 }; // '(', ')', '{', '}'
 
        while (!in.eof())
        {
            char symbol = static_cast<char>(in.get());
 
            switch (symbol)
            {
                case '(':
                {
                    symbols[0]++;
                    break;
                }
 
                case ')':
                {
                    symbols[1]++;
                    break;
                }
 
                case '{':
                {
                    symbols[2]++;
                    break;
                }
 
                case '}':
                {
                    symbols[3]++;
                    break;
                }
            }
        }
 
        out << "( = " << symbols[0] << endl
            << ") = " << symbols[1] << endl
            << "{ = " << symbols[2] << endl
            << "} = " << symbols[3] << endl;
 
        in.close();
        out.close();
 
        if (symbols[0] == symbols[1])
            cout << "OK1" << endl;
        else cout << "ERROR1" << endl;
 
        if (symbols[2] == symbols[3])
            cout << "OK2" << endl;
        else cout << "ERROR2" << endl;
    }
    else cout << "Error opening files." << endl;
 
    cin.get();
 
    return 0;
}
В таком виде все работает нормально, при входном файле
{{}}
()
выдаст
( :1
) :1
{ :2
} :2

Но если заменить строку 18 на
C++
1
2
char symbol;
in.get(symbol);
то в выводе будет добавлен один лишний символ, который последний в файле, в данном случае
( :1
) :2
{ :2
} :2

При этом, если в конец файла добавить пустую строку, второй вариант тоже нормально отработает. Объясните в чем разница... Заранее благодарю.
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
03.03.2016, 01:26
Ответы с готовыми решениями:

ifstream
Привет всем такая проблема ввода Student* s;// студенты s = new Student; ifstream fin(&quot;Student.txt&quot;); for(int i(0); i...

fstream ifstream
подключил библиотеку fstream создал объект ifstream file открыл файл, поработал(считывал до конца &lt; eof()) сделал file.close(); ...

Ifstream ошибка
int main(int argc, char* argv) { setlocale(LC_ALL,&quot;Russian&quot;); // корректное отображение Кириллицы char buff; // буфер...

7
1378 / 522 / 72
Регистрация: 21.07.2015
Сообщений: 1,308
03.03.2016, 02:04
Цитата Сообщение от elephants Посмотреть сообщение
Код ниже проверяет баланс скобок
Неправильный. Не отловит ситуацию )(
1
Эксперт С++
 Аватар для grizlik78
2382 / 1666 / 279
Регистрация: 29.05.2011
Сообщений: 3,402
03.03.2016, 02:06
Лучший ответ Сообщение было отмечено elephants как решение

Решение

Разница в том, что если пытаться читать из файла после достижения конца файла, то вариант get() вернёт EOF, а вариант get(symbol) значение переменной не изменит, а там предыдущий считанный символ.
Проблема в том, что признак конца файла устанавливается не после считывания последнего символа, а при попытке считать следующий. То есть проверять надо после чтения, а не до.
То есть, например
C++
1
2
3
4
5
        while (!in.eof())
        {
            int symbol  = in.get();
            if (symbol == EOF)
                break();
или
C++
1
2
3
4
5
        while (!in.eof())
        {
            char symbol;
            if (!in.get(symbol))
                break();
или даже так
C++
1
2
3
        char symbol;
        while (in.get(symbol))
        {
2
26 / 26 / 15
Регистрация: 30.12.2015
Сообщений: 95
03.03.2016, 02:14  [ТС]
Цитата Сообщение от shmkv Посмотреть сообщение
Неправильный. Не отловит ситуацию )(
Код не мной написан, особо не вникал. Интересовал именно описанный мной момент.
grizlik78, Благодарю.
0
1378 / 522 / 72
Регистрация: 21.07.2015
Сообщений: 1,308
03.03.2016, 02:19
Касаемо второго варианта, то можно вкорячить проверку eof сразу после get. С такой работай я его тоже сталкивался, но в причинах не разбирался.

Добавлено через 3 минуты
Цитата Сообщение от grizlik78 Посмотреть сообщение
устанавливается не после считывания последнего символа, а при попытке считать следующий
Ну примерно так и думал.
0
26 / 26 / 15
Регистрация: 30.12.2015
Сообщений: 95
03.03.2016, 02:21  [ТС]
Цитата Сообщение от shmkv Посмотреть сообщение
то можно вкорячить проверку eof сразу после get.
Я так и делал, просто непонятно было, почему symbol не изменяется после чтения отсутствующих данных через get(symbol).
0
1378 / 522 / 72
Регистрация: 21.07.2015
Сообщений: 1,308
03.03.2016, 02:22
Ну вот разработчики как-то так решили. Видимо, из соображений, что в char не запихать EOF.
0
26 / 26 / 15
Регистрация: 30.12.2015
Сообщений: 95
03.03.2016, 02:23  [ТС]
Цитата Сообщение от grizlik78 Посмотреть сообщение
что признак конца файла устанавливается не после считывания последнего символа, а при попытке считать следующий.
Это понятно, а вот про
Цитата Сообщение от grizlik78 Посмотреть сообщение
Разница в том, что если пытаться читать из файла после достижения конца файла, то вариант get() вернёт EOF, а вариант get(symbol) значение переменной не изменит
я не знал.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
03.03.2016, 02:23
Помогаю со студенческими работами здесь

Объект ifstream!!!
Скажите пожалуйста, почему при создании объекта ifstream(например fin) и привязке его к определенному файлу (ifstream fin(filename);), и...

ifstream ofstream
как работают данные файловые операции, объясните пожалуйста куда происходит запись ена жёстком диске

не работает в ifstream
Сам очень плохо разбираюсь в &lt;fstream&gt; Вот код, который должен &quot;записывать и выводить&quot; данные из ранее записанного текстового...

ifstream считывает 0
Здравствуйте. Есть 2 текстовых файла с названиями n.in n.out .Содержимое входящего файла 1 5 2 4 3 9 4 7 5

Unget and ifstream
Я правильно понимаю, что если ifstream in; string str1; in &gt;&gt; str1, то unget обратно эту строку вернет?


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru