Мне нужна следующая программа, чтобы взять всю строку пользовательского ввода и поместить ее в строковые имена:
cout << "Enter the number: ";
int number;
cin >> number;
cout << "Enter names: ";
string names;
getline(cin, names);
С cin >> number
команда перед getline()
Команда (однако, я думаю, это проблема), она не позволит мне вводить имена. Зачем?
Я слышал что-то о cin.clear()
команда, но я понятия не имею, как это работает или почему это даже необходимо.
cout << "Enter the number: ";
int number;
if (cin >> number)
{
// throw away the rest of the line
char c;
while (cin.get(c) && c != '\n')
if (!std::isspace(c))
{
std::cerr << "ERROR unexpected character '" << c << "' found\n";
exit(EXIT_FAILURE);
}
cout << "Enter names: ";
string name;
// keep getting lines until EOF (or "bad" e.g. error reading redirected file)...
while (getline(cin, name))
...use name...
}
else
{
std::cerr << "ERROR reading number\n";
exit(EXIT_FAILURE);
}
В приведенном выше коде этот бит …
char c;
while (cin.get(c) && c != '\n')
if (!std::isspace(c))
{
std::cerr << "ERROR unexpected character '" << c << "' found\n";
exit(EXIT_FAILURE);
}
…проверяет оставшуюся часть строки ввода после того, как число содержит только пробел.
Это довольно многословно, поэтому с помощью ignore
в потоке после >> x
это часто рекомендуемый альтернативный способ отбросить контент до следующей новой строки, но при этом он рискует выбросить непробельный контент и при этом пропустить поврежденные данные в файле. Вы можете или не можете заботиться, в зависимости от того, является ли содержимое файла надежным, насколько важно избежать обработки поврежденных данных и т. Д.
Так, std::cin.clear()
(а также std::cin.igore()
) не обязательно для этого, но полезно для устранения состояния ошибки. Например, если вы хотите дать пользователю много шансов для ввода правильного номера.
int x;
while (std::cout << "Enter a number: " &&
!(std::cin >> x))
{
if (std::cin.eof())
{
std::cerr << "ERROR unexpected EOF\n";
exit(EXIT_FAILURE);
}
std::cin.clear(); // clear bad/fail/eof flags
// have to ignore non-numeric character that caused cin >> x to
// fail or there's no chance of it working next time; for "cin" it's
// common to remove the entire suspect line and re-prompt the user for
// input.
std::cin.ignore(std::numeric_limits<std::streamsize>::max());
}
Еще одна простая, но недоделанная альтернатива ignore
для вашего первоначального требования использует std::skipws
пропустить любое количество пробелов перед чтением строк …
if (std::cin >> number >> std::skipws)
{
while (getline(std::cin, name))
...
…но если он получит ввод, такой как «1E6» (например, какой-то ученый пытается ввести 1 000 000, но C ++ поддерживает только эти обозначения для чисел с плавающей запятой), не примет это, вы в конечном итоге получите number
установлен в 1
, а также E6
читать как первое значение name
, Отдельно, если у вас есть правильный номер, за которым следуют одна или несколько пустых строк, эти строки будут игнорироваться.
cout << "Enter the number: ";
int number;
cin >> number;
cin.ignore(256, '\n'); // remaining input characters up to the next newline character
// are ignored
cout << "Enter names: ";
string names;
getline(cin, names);
Еще один способ сделать это, чтобы положить
cin.ignore ( std::numeric_limits<std::streamsize>::max(), '\n' );
после вашего cin>>number;
полностью очистить входной буфер (отвергая все лишние символы, пока не будет найдена новая строка). Вам нужно #include <limits>
чтобы получить max()
метод.
Пытаться:
int number;
cin >> number;
char firstCharacterOfNames;
cin >> firstCharacterOfNames; // This will discard all leading white space.
// including new-line if there happen to be any.
cin.unget(); // Put back the first character of the name.
std::string names;
std::getline(cin, names); // Read the names;
В качестве альтернативы. Если вы знаете, что номер и имена всегда будут в разных строках.
cin >> number;
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::getline(cin, names);
Вы можете использовать std :: ws для извлечения любых пробельных символов во входном буфере перед использованием getline. Заголовок для std :: ws является sstream.
cout << "Enter the number: ";
int number;
cin >> number;
cout << "Enter names: ";
string names;
cin>>ws;
getline(cin, names);
Или вы можете очистить входной буфер, чтобы прочитать строку
fflush (STDIN)
это определено в заголовке stdio.h.
Этот код работает ..
cout << "Enter the number: ";
int number;
cin >> number;
cout << "Enter names: ";
string names;
fflush(stdin); //FLUSHING STDIN
getline(cin, names);
cout << "Enter the number: ";
int number;
cin >> number;
cout << "Enter names: ";
string names;
getline(cin, names);//works on the \n left behind
getline(cin, names);//continues and rewrites names
это довольно самоочевидно, в потоке осталось \ n cin >> number
использует, который присваивается именам при первом использовании. Повторное использование getline пишет правильное значение сейчас.
Вы можете найти ответ, который вы хотите в cppreference.
При использовании сразу после ввода через пробел, например, после
int n; std::cin >> n;
getline использует символ конца строки, оставленный во входном потоке оператором >>, и возвращает результат немедленно. Распространенным решением является игнорирование всех оставшихся символов в строке ввода с помощьюcin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
перед переключением на линейно-ориентированный ввод.