Я изучаю c++, и мне нужно создать структуру "Студент" в c++ и работать с ней (я использую Microsoft Visual c++ 2010 Express)
Я создал файл Student.cpp
#include "stdafx.h"
using namespace std;
const int num = 5;
struct Student {
char name[30];
int groupNumber;
int progress[num];
};
и это моя программа
#include "stdafx.h"
#include "Student.cpp"
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
setlocale (LC_ALL, "Russian");
srand((unsigned)time(NULL));
int n;
cout << "Введите количество студентов в группе n = ";
cin >> n;
Student * Group = new Student[n];
for (int i = 0; i < n; ++i)
{
cout << "Введите ФИО: ";
cin >> Group[i].name;
Group[i].groupNumber = rand()%5 + 1;
for (int j = 0; j < num; ++j)
{
Group[i].progress[j] = rand()%5 + 2;
}
}
for (int i = 0; i < n; ++i)
{
int sum = 0;
for (int j = 0; j < num; ++j)
{
sum += Group[i].progress[j];
}
double count = (double)sum/5;
if (count < 4) continue;
cout << "\n\n" << Group[i].name << "\nГруппа: " << Group[i].groupNumber << "\nСредний бал: " << count;
}
cout << "\n\n";
delete [] Group;
system("PAUSE");
return 0;
}
но когда я попытался ввести имя с помощью пробела (например, имя и фамилия для одного ученика), я получил ошибку, так как мой круг пропустил один шаг
Я попытался использовать string
для имени
string name
но проблема остается прежней.
Что не так и как это исправить?
У вас есть пара проблем с вашим кодом, но в отношении того, о котором вы просите об этом, потому что оператор ввода >>
читает пробелы, разделенные токенами. Поэтому, если у вас есть предложение с пробелом (например, пробел, табуляция, новая строка), вы получите только первое "слово".
Вместо этого используйте std::getline
.
Я попытаюсь объяснить, что вызывает эту ошибку.
Представьте, что внутри cin
есть буфер, который в основном представляет собой массив char
s:
END
|
+---+---+---+---+---+---+---+---+---+
| | | | | | | | | |
+---+---+---+---+---+---+---+---+---+
В настоящий момент буфер пуст (как я пытался показать с помощью END "point" в первой ячейке). Когда вы говорите cin >> name
первое, что делает cin
, - это проверить, есть ли что-либо в настоящее время в буфере. Если нет, он запрашивает и копирует ваш вход в буфер:
END
|
+---+---+---+---+---+---+---+---+---+
| H | e | l | l | o | | ! |\n | |
+---+---+---+---+---+---+---+---+---+
Теперь он копирует то, что находится в буфере (до символа "белого пробела") в name
и перемещает содержимое буфера вниз. Итак, теперь name == "Hello"
и буфер выглядит следующим образом:
END
|
+---+---+---+---+---+---+---+---+---+
| | ! |\n | | | | | | |
+---+---+---+---+---+---+---+---+---+
Обратите внимание, как буфер не пуст. В следующий раз, когда вы сделаете cin >> name
он выполнит ту же проверку и увидит, что в буфере уже есть что-то, поэтому он не запрашивает. Вот почему ваш текст печатается, не спрашивая ни о чем. cin >> name
присвоит name
значение "!"
(он пропустит пространство впереди), но буфер все еще не пуст; он все еще имеет символ \n
(с момента нажатия Enter). getline
проглатывает эту новую строку, но не включает ее в результат.
cin.clear()
в мой код после cout
в cout << "Введите ФИО: "; getline (cin, Group[i].name);
но я дважды получил cout
i.imgur.com/o3kjVFt.png . Как это исправить?
5
буфер выглядит как 5\n
; когда вы делаете cin >> n
\n
в буфере все еще есть \n
. Первый std::getline
вернет пустую строку. Вы должны сделать cin.ignore()
после строки cin >> n
. У вас была правильная идея с cin.clear()
но это делает что-то другое.
cin >>
потеряет пробелы. попробуйте использовать cin.getline()
.
cin.getline
разницу:std::getline
неcin.getline
!