Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
Kris_
1 / 1 / 3
Регистрация: 09.11.2014
Сообщений: 64
1

Неправильная последовательность ввода/вывода в консоли

15.08.2018, 21:44. Просмотров 850. Ответов 13

Ввод информации о первом студенте правильно работает, а дальше уже нет. Это не мой код и мне сложно в нём разобраться и найти ошибку. Поэтому очень нуждаюсь в вашей помощи.

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
#include "stdafx.h"
#include <iostream>
#include <string.h>
#include <stdio.h>;
using namespace std;
 
 
void main()
{
    setlocale(LC_ALL, "Russian");
    const int n = 5;
    int i;
    float sm, sf, sp;
    struct stud
    {
        char fam[25];
        int mat, fiz, prg;
        float sb;
    }
    ved[n]; 
    sm = sf = sp = 0;
    
    for (i = 0; i < n; i++)
    {
        cout << "***** Введите информацию о " << (i + 1) << " студенте\n";
        cout<<"Введите фамилию и инициалы\n";
        gets_s(ved[i].fam);
        cout << "Оценки по матем., физике и программир.\n";
        cin >> ved[i].mat >> ved[i].fiz >> ved[i].prg;
        
        ved[i].sb = (float(ved[i].mat + ved[i].fiz + ved[i].prg)) / 3;
        
        sm += ved[i].mat; sf += ved[i].fiz; sp += ved[i].prg;
    }
    //--------------------- вывод результатов вычислений
    cout << "\n******* Результаты сессии\n";
        cout.precision(3);
    for (i = 0; i < n; i++)
        cout << i + 1 << " " << ved[i].fam << " матем. = " << ved[i].mat << " физика = " << ved[i].fiz << "програм. = " << ved[i].prg << " ср. балл = " << ved[i].sb << "\n";
    cout << "\n\nСредний балл группы по математике = " << sm / n;
    cout << "\nСредний балл группы по физике = " << sf / n;
    cout << "\nСредний балл группы по программированию = " << sp / n;
    cout << "\n\n***** Отличники по программированию: \n";
    for (i = 0; i < n; i++)
        if (ved[i].prg == 5)
            cout << ved[i].fam << "\n";
    cin >> i;
}
0
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.08.2018, 21:44
Ответы с готовыми решениями:

Кодировка ввода вывода консоли под кириллицу и латиницу
Возникла необходимость одновременной работы кириллицы и латиницы в...

Неправильная кодировка в консоли
#include &quot;stdafx.h&quot; #include &lt;iostream&gt; using namespace std; const int...

Неправильная работа вывода текста в input
Вот при нажатии на кнопку то есть input должно в окне высвечиваться значение...

Ошибка ввода\вывода 104, файле не открыт для ввода (строка 0)
Всё работает, но пишет: &quot;ошибка ввода\вывода 104, файле не открыт для ввода...

Ошибка ввода/вывода 104 - файл не открыт для ввода
var a:array of integer; n,j,i,k: integer; f:text; begin ...

13
mvngr
112 / 94 / 65
Регистрация: 15.04.2018
Сообщений: 353
15.08.2018, 22:37 2
Цитата Сообщение от Kris_ Посмотреть сообщение
sm = sf = sp = 0;
Сразу видно - писал питонист, так в плюсах делать очень нежелательно. Отдельно каждую переменную присваивайте нулю.

Пожалуйста, почитайте про debug'ер, как им пользоваться. Это очень сильно облегчит вам работу
1
Kris_
1 / 1 / 3
Регистрация: 09.11.2014
Сообщений: 64
15.08.2018, 22:53  [ТС] 3
С его помощью поискать ошибку? Думала об этом, но не очень много есть опыта работы с ним.
0
mvngr
112 / 94 / 65
Регистрация: 15.04.2018
Сообщений: 353
15.08.2018, 23:31 4
Kris_, очень простая в обращении штука, найдите видео с примером использования. Когда будете гуглить - вводите название программы, в которой вы программируете. А главное - очень, очень полезная для новичков
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
4835 / 2480 / 695
Регистрация: 18.10.2014
Сообщений: 4,288
16.08.2018, 01:15 5
Цитата Сообщение от mvngr Посмотреть сообщение
Сразу видно - писал питонист, так в плюсах делать очень нежелательно. Отдельно каждую переменную присваивайте нулю.
Это почему это?

Добавлено через 1 минуту
Цитата Сообщение от Kris_ Посмотреть сообщение
Ввод информации о первом студенте правильно работает, а дальше уже нет.
Что означает эта фраза?
1
Kris_
1 / 1 / 3
Регистрация: 09.11.2014
Сообщений: 64
16.08.2018, 10:51  [ТС] 6
Лучше покажу:
0
Миниатюры
Неправильная последовательность ввода/вывода в консоли  
CheshireCat
Эксперт С++
2913 / 1262 / 114
Регистрация: 27.05.2008
Сообщений: 3,464
16.08.2018, 12:23 7
Цитата Сообщение от mvngr Посмотреть сообщение
Сразу видно - писал питонист, так в плюсах делать очень нежелательно. Отдельно каждую переменную присваивайте нулю.


Обоснуй.
0
moskitos80
69 / 69 / 33
Регистрация: 04.10.2011
Сообщений: 245
Завершенные тесты: 1
17.08.2018, 13:12 8
Спасибо за задачку Потренировался чуток (платформа gcc (Debian 6.3.0-18+deb9u1) 6.3.0) под венду лень было затачивать, так что можете потрудиться и сделать это сами:

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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#include <iostream>
#include <vector>
#include <string>
#include <stdexcept>
#include <functional>
 
using namespace std;
 
struct student_t
{
    int physics;
    int mathematics;
    int programming;
    string full_name;
 
    float getAverage() const {
        return (float(
            this->physics +
            this->mathematics +
            this->programming)) / 3;
    }
};
 
template<typename T>
istream& requireInput(
        istream& istr,
        T& result,
        function<T(const string&)> convert_fn,
        const string& err_msg = "Ошибка. Повторите ввод: ")
{
    do {
        string str_line;
        // Здесь ошибка возможна только при закрытии потока Ctrl+D или аппаратном сбое
        getline(istr, str_line);
        // Если не нажат Ctrl+D
        if (istr) {
            // пробуем преобразовать полученную строку в нужный тип
            try {
                result = convert_fn(str_line); break;
            } catch (const invalid_argument&) {
                cerr << err_msg; // ну, не Шмогла я :) пробуем заново...
            }
        }
    } while (istr);
 
    return istr;
}
 
/**
 * Напечатать заголовок
 * работает корректно только с юникодом. Не наш случай :)
 * Но кое какую красоту обеспечивает
 */
void printHeader(ostream& ostr, const string& message, char decor, int line_size = 79)
{
    int half_line_size = line_size / 2,
        half_msg_size  = message.size() / 2,
        // 2 - вычитаем еще пару пробелов, которые добавим ниже
        decor_char_count = half_line_size - half_msg_size - 2;
 
    ostr << endl << endl
       << string(decor_char_count, decor)
       << " " << message << " "
       << string(decor_char_count, decor)
       << endl << endl;
}
 
ostream& operator << (ostream& os, const student_t& student)
{
    return os << student.full_name << endl
              << "Математика = " << student.mathematics << endl
              << "Физика = " << student.physics << endl
              << "Программирование = " << student.programming << endl
              << "Средний балл = " << student.getAverage() << endl << endl;
}
 
istream& operator >> (istream& is, student_t& student)
{
    // В коде ниже requireInput вернет false только если пользователь нажал Ctrl+D
    cout << "Введите фамилию и инициалы студента: ";
    if (!requireInput<string>(is, student.full_name, [](const string& str){
        if (str.size() == 0) { throw invalid_argument(""); }
        return str;
    })) { return is; }
 
    cout << "Введите оценку студента по математике: ";
    if (!requireInput<int>(is, student.mathematics, [](const string& str){
        return stoi(str);
    })) { return is; }
 
    cout << "Введите оценку студента по физике: ";
    if (!requireInput<int>(is, student.physics, [](const string& str){
        return stoi(str);
    })) { return is; }
 
    cout << "Введите оценку студента по программированию: ";
    return requireInput<int>(is, student.programming, [](const string& str){
        return stoi(str);
    });
}
 
using student_group_t = vector<student_t>;
 
/** Заносим студеров в гуппу */
bool populate_student_group(student_group_t& group)
{
    for(int i = 1; cin; i++)
    {
        student_t student;
        cout << "Введите информацию о студенте " << i << endl
             << "Или нажмите <Ctlr+D> и <RETURN> для продолжения." << endl;
        if (cin >> student) {
            group.push_back(student);
        } cout << endl;
    }
    return group.size();
}
 
int main()
{
    setlocale(LC_ALL, "");
 
    student_group_t student_group;
    size_t group_size = populate_student_group(student_group);
 
    // Если в группе есть студенты:
    if (group_size > 0)
    {
        printHeader(cout, "Результаты сессии", '*');
 
        float average_math = 0,
              average_phys = 0,
              average_prog = 0;
 
        vector<student_t> excellent_students_programming;
        for(const student_t& stud: student_group)
        {
            cout << stud << endl;
            average_math += stud.mathematics;
            average_phys += stud.physics;
            average_prog += stud.programming;
            if (stud.programming == 5) {
                excellent_students_programming.push_back(stud);
            }
        }
 
        cout << "Средний балл группы по физике = " << average_phys / group_size << endl
             << "Средний балл группы по математике = " << average_math / group_size << endl
             << "Средний балл группы по программированию = " << average_prog / group_size << endl;
 
        printHeader(cout, "Отличники по программированию", '*');
        for(const auto& stud: excellent_students_programming) {
            cout << stud << endl;
        }
    }
 
    cout << "Нажмите <RETURN> что бы выйти из программы ...";
    cin.clear(); // на случай если был нажат Ctlr+D
    cin.get(); // стопорим окошко, ожидая ввод
 
    return 0;
}
0
Kris_
1 / 1 / 3
Регистрация: 09.11.2014
Сообщений: 64
17.08.2018, 13:18  [ТС] 9
Спасибо за старания! Но я бы хотела найти ошибку в моём коде, а не просто получить решение. Хочеться понять почему не так работает, как должно бы.
0
Croessmah
++Ͻ
14776 / 8452 / 1605
Регистрация: 27.09.2012
Сообщений: 20,800
Записей в блоге: 2
Завершенные тесты: 1
17.08.2018, 13:26 10
После ввода числа в потоке остался символ переноса строки и, как следствие, gets_s читает пустую строку.
0
moskitos80
69 / 69 / 33
Регистрация: 04.10.2011
Сообщений: 245
Завершенные тесты: 1
17.08.2018, 13:45 11
Лучший ответ Сообщение было отмечено Kris_ как решение

Решение

Отрадно слышать, что человек хочет разобраться, а не получить решение "на шару". На самом деле Это классический "затык" когда мы пытаемся считывать более одного значения из потока ввода. Поток ввода в вашем случае объект cin имеет некоторые свойства, которые определяют его поведение. Например поток имеет внутренний буфер. В котором очень часто остается символ новой строки после того как нажали клавишу ввод а если в буфере что то есть то поток не блокирует ход выполнения программы, а тупо достает из буфера оставшиеся символы.

Вот тут можно почитать про подобные ловушки подробно и найти пути их решения: Tips and tricks for using C++ I/O (input/output) Подходом оттуда я кстати и воспользовался, когда писал вам код

В вашем случае мне удалось реанимировать работу вашей программы, поясню как. Добавьте заголовок в самый верх файла:

C++
1
#include <limits>
и после строки, где вы считываете введенные оценки:

C++
1
2
3
...
cin >> ved[i].mat >> ved[i].fiz >> ved[i].prg; // в вашем примере строка 29
cin.ignore(numeric_limits<int>::max(), '\n'); // Добавьте этот код
Это должно заставить программу работать, но код вашего примера очень не "устойчив" и любые погрешности ввода обвалят программу.
Я же дал вам код который более устойчив к ошибкам ввода.
1
Kris_
1 / 1 / 3
Регистрация: 09.11.2014
Сообщений: 64
17.08.2018, 14:59  [ТС] 12
Спасибо большое за прекрасное объяснение и понимание!!!! Обязательно изучу и ваш вариант решения!)
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
4835 / 2480 / 695
Регистрация: 18.10.2014
Сообщений: 4,288
17.08.2018, 16:37 13
Цитата Сообщение от Kris_ Посмотреть сообщение
Лучше покажу:
И что мы должны увидеть на этом скриншоте? Где на нем какие-то отклонения от нормы?
0
Kris_
1 / 1 / 3
Регистрация: 09.11.2014
Сообщений: 64
17.08.2018, 17:25  [ТС] 14
Там видно разницу между вводом и выводом информации о 1 и о 2 студенте
0
17.08.2018, 17:25
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.08.2018, 17:25

Неправильная работа устройств ввода
Со вчерашнего дня появилась такая проблема: Клавиатура неожиданно перестала...

Неправильная последовательность действий
Есть такой код: infoPanel.append(&quot;Идет кодирование..\n&quot;); ...

Неправильная работа цикла ввода строки
Есть программа: Program abc; var i,n:integer; s:string; begin


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

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

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