Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
TrickSonix
1 / 1 / 0
Регистрация: 04.07.2013
Сообщений: 12
#1

Пропускает операторы считывания информации после первой итерации - C++

22.08.2013, 21:31. Просмотров 779. Ответов 3
Метки нет (Все метки)

Доброго времени суток всем. Все кому лень читать предистории можете смело пропускать следующие строки, смотреть на код, и возникшую проблему которую я опишу под ним.
Я лишь недавно занялся изучением С++ по книге Дейтелов. На протяжении первых 5-6 глав там мусолят класс под названием GradeBook. Ну и я следуя инструкциям, и некоторым своим соображениям мусолил этот же класс вместе с книгой. В 5-ой главе, когда демонстрируют оператор выбора switch представляют текст программы на С++ этого класса вместе с добавлением сего оператора. Суть - считывание буквенных оценок, и, по окончанию ввода, вывод количества различных буквенных оценок. Кому интересно, в книге это страница 282(издание 2008 года). Мой же собственный код отличается от этого тем, что я попытался сделать так чтобы эта программа работала столько раз, сколько я захочу (цикл while с меткой). Вот как это получилось в итоге:
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
#include <cstdlib>
#include <iostream>
#include <string>
#include "GradeBook.h"
 
using namespace std;
 
int main()
{
    string nameOfCourse;
    string name;
    int choise = 0;
    char k = 'n';
    cout << "Enter name: " << endl;
    getline(cin, name);
    GradeBook gradeBook1(name); //создание класса с именем gradeBook1
 
    cout << "gradeBook1 created for: " << gradeBook1.getCourseName() << endl;
    do
    {
        cout << "\nPlease enter the course name for gradeBook:" << endl;
        getline( cin, nameOfCourse );
        gradeBook1.setCourseName(nameOfCourse); //эта функция изменяет первоначальное имя курса
        cout << endl;
    
        gradeBook1.displayMessage();
        cout << "\nWhat kind of operation would have you do?" << "\n1)Determine Class Average\n2)Input letter grades" << endl;
        cin >> choise;
        if (choise == 1)
        {
            gradeBook1.determineClassAverage();
        }
        else
        {
            if (choise == 2)
            {
                gradeBook1.inputGrades(); // а вот и функция которая считывает буквенные оценки и записывает их количесвто в свои внутренние переменные
                gradeBook1.displayGradeReport(); // Это функция отображения полученного результата после окончания ввода
            }
            else
                cout << "Incorrect number of operation." << endl;
        }
        cout << "Continue? (y/n)" << endl;
        cin >> k;
    }
    while (k != 'n'); //по умолчанию пользователь не хочет продолжать работать с программой и нужно ввести y чтобы продолжить
    system("PAUSE");
   return 0;
}
А вот собственно и проблема - после того как цикл срабатывает первый раз перестают работать некоторые операторы ввода информации. Если, например, ввести неправильно номер операции то он просто выдает текст который выводят все функции cout до момента когда нужно выбрать операцию. А если же выбрать операцию 2 то после того как заканчиваешь вводить оценки(признаком конца ввода является символ EOF) цикл начинает повторяться до бесконечности.
Ниже написаны функции класса, на всякий случай.
Для создания программ пользуюсь Dev-cpp 4.9.9.2
Кликните здесь для просмотра всего текста
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include "GradeBook.h"
 
using namespace std;
 
GradeBook::GradeBook(string name)
{
    setCourseName(name);
    aCounter = 0;
    bCounter = 0;
    cCounter = 0;
    dCounter = 0;
    fCounter = 0;
}
 
void GradeBook::setCourseName(string name)
{
    if (name.length() <= 25)
        courseName = name;
    else
    {
        courseName = name.substr(0,25);
        cout << "Name \"" << name <<"\" exceed maximum length.\nLimiting courseName to first 25 characters.\n" << endl;
    }
}
 
string GradeBook::getCourseName()
{
    return courseName;
}
 
void GradeBook::displayMessage()
{
    cout << "Welcome to Grade Book for\n" << getCourseName() << "!" << endl;
}
 
void GradeBook::determineClassAverage()
{
    int gradeCounter = 0;
    int grade = 0;
    double average = 0;
    int total = 0;
    cout << "Enter grade or -1 to end: " << endl;
    cin >> grade;
    while (grade != -1)
    {
        gradeCounter += 1;
        total = total + grade;
        cout << "Enter grade or -1 to end: " << endl;
        cin >> grade;       
    }
    if (gradeCounter != 0)
    {
        average = static_cast<double>(total)/gradeCounter;
        cout << "\nTotal of all " << gradeCounter << " grades entered is " << total << endl;
        cout << "Class average is " << setprecision(2) << fixed << average << endl;
    }
    else
        cout << "No grades were entered." << endl;
}
 
void GradeBook::inputGrades()
{
    int grade = 0;
    cout << "Enter the letter grades." << endl << "Enter the EOF character to end input." << endl;
 
    while ((grade = cin.get()) != EOF)
    {
        switch (grade)
        {
            case 'A':
            case 'a':
                aCounter++;
                break;
            case 'B':
            case 'b':
                bCounter++;
                break;
            case 'C':
            case 'c':
                cCounter++;
                break;
            case 'D':
            case 'd':
                dCounter++;
                break;
            case 'F':
            case 'f':
                fCounter++;
                break;
            case '\n':
            case '\t':
            case ' ':
                break;
            default:
                cout << "Incorrect letter grade entered. Enter another." << endl;
                break;
        }
    }
}
 
void GradeBook::displayGradeReport()
{
    cout << "\nNumber of students who received each letter grade:"
        << "\nA: " << aCounter
        << "\nB: " << bCounter
        << "\nC: " << cCounter
        << "\nD: " << dCounter
        << "\nF: " << fCounter
        << endl;
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
22.08.2013, 21:31
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Пропускает операторы считывания информации после первой итерации (C++):

Не получается после первой итерации считать во вложенном (ss>>ch) - C++
Код вычисляет (вернее должен ) сумму чисел в числе,затем считывает обратно в поток stringstream и делает то же снова пока сумма не будет...

Почему не меняется imin после первой итерации? - C++
void solution() { bool flag; for (int i =m-2; i&gt;=0; i--) { flag = false; if (imin - 1 &gt;= 0&amp;&amp; imin + 1 &lt;...

Программа пропускает ввод первой строки - C++
здраствуйте. в коде програмы, приведенном ниже, в структуру Track записываются данные, считанные с клавиатуры(функция Track...

Есть ли в С++ функция для считывания информации с файла с подробной настройкой? - C++
Есть ли в С++ функция для считывания информации с файла с подробной настройкой?Мне нужно будет потом их записать в массив. Ну вот например...

Пропуск вызова cin.getline в первой итерации цикла - C++
В цикле заполнения массива значениями консоль выводит два раза &quot;В цикле&quot;, а только потом начинает считывать данные, может кто-нибудь знает...

Пропускает ввод данных после for - C++
После заполнения вектора и выхода из цикла for программа завершается . Почему компилятор не переходит к следующему циклу while ? . ...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
alsav22
5417 / 4813 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
22.08.2013, 21:38 #2
Если после cin >> идёт getline() или cin.get(), то нужно так писать:
C++
1
2
3
4
...
(cin >> choise).get();
...
(cin >> k).get();
...
А лучше, на всякий случай, всегда так писать.
TrickSonix
1 / 1 / 0
Регистрация: 04.07.2013
Сообщений: 12
22.08.2013, 21:46  [ТС] #3
Спасибо, помогло. А не могли бы вы объяснить, если вам не сложно, в чем разница между простым оператором cin и оператором написанным подобным образом? Ну то есть в чем суть явления описанного мной казуса?
alsav22
5417 / 4813 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
22.08.2013, 22:04 #4
После работы cin >> в потоке чтения остаётся символ новой строки '\n' (попадает туда при нажатии Enter). Если функция getline() встречает такой символ первым, то для неё это пустая строка: чтение останавливается, символ '\n' извлекается из очереди (в отличие от get(char* s, streamsize n)), но не сохраняется, в строку ввода помещается '\0' . Флаг ошибки НЕ устанавливается (в отличие от get(char* s, streamsize n)), код идёт дальше.

Добавлено через 3 минуты
А в inputGrades(), функция cin.get() просто извлечёт '\n', оставшийся в потоке, и код, без остановки на ввод, пойдёт дальше.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.08.2013, 22:04
Привет! Вот еще темы с ответами:

Переменной типа int при первой итерации цикла приписывается значение меньше на 1 - C++
Доброго времени суток. Возникла проблема которую видно на скриншоте. Получаеться что если выводить значение переменной то получаем...

Не даёт вводить (пропускает, проходит мимо), после первого ввода - C++
Здравствуйте такая проблема: Надо строку с пробелами записать в массив (всё вроде просто: используй gets() и ок, но не там было) Когда...

Строки: уничтожить в строке запятые перед первой точкой, заменить знаком + все цифры 3я после первой точки - C++
Дано строка длиной n символов, среди которых есть хотя бы одна точка. превратить последовательность s1, s2, ... sn, уничтожив в ней все...

Встретил незнакомые операторы, нужно больше информации - C++
Здравствуйте, встретил в одном из уроков такой пример: bool t = false; t = a &gt; b; cout &lt;&lt; a &lt;&lt; (t==true ? &quot; &gt; &quot; : &quot; &lt;= &quot;) &lt;&lt; b;...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
22.08.2013, 22:04
Ответ Создать тему
Опции темы

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