std :: cin ввод с пробелами?


154
#include <string>

std::string input;
std::cin >> input;

Пользователь хочет ввести «Hello World». Но cinне получается пробел между двумя словами. Как я могу понять cinвсе Hello World?

Я действительно делаю это со структурами и cin.getline, похоже, не работает. Вот мой код:

struct cd
{
    std::string CDTitle[50];
    std::string Artist[50];
    int number_of_songs[50];
};

std::cin.getline(library.number_of_songs[libNumber], 250);

Это приводит к ошибке. Любые идеи?


27
Вы не должны редактировать свои вопросы, чтобы задавать новые подобные вопросы. Причина в том, что люди уже дали ответы на ваш исходный вопрос, и теперь эти ответы кажутся вырванными из контекста. Если на ваш исходный вопрос уже был дан ответ, просто задайте новый вопрос, чтобы избежать путаницы.
— Пит

Это очевидно после небольшого изучения, но не могли бы вы добавить объявление для переменной, libraryчтобы было ясно, что она относится к типуcd
— chandsie

извините, ребята, это было сделано на скорую руку, я сделаю репост.
— лимон

1
Если вы собираетесь репостить его в качестве замены, отметьте вопрос для удаления модом.
— Гонки легкости на орбите

2
В вашем обновлении, вы пытаетесь getlineв int. Конечно, это не удается.
— Бен Фойгт

Ответы:


106

Вы должны использовать cin.getline():

char input[100];
cin.getline(input,sizeof(input));

7
@Kevin Meh, такое бывает. C ++ не такой интуитивно понятный, как хотелось бы.
— Пит

64
Ew; зачем использовать char-буферы? Это 2011.
— Lightness Races in Orbit

4
А почему бы не использовать cin.getline(input, sizeof(input));? Кроме того, не следует ли вам проверять статус возврата?
— Джонатан Леффлер

2
@JonathanLeffler В то время, когда это было написано, это был ответ, который у меня был на вопрос, который изначально был задан (посмотрите на первый комментарий к фактическому вопросу, и вы увидите, что контекст изменился из-за редактирования OP). В любом случае, если вы чувствуете, что ответ настолько ужасен, проголосуйте против. Я признаю, что это может быть не «лучшее» решение, но это решение не в меньшей степени. Вместо того, чтобы спрашивать, почему я что-то не использовал, вы могли бы рассказать нам всем, почему мы должны делать это по-вашему.
— Pete

7
Ваш ответ не ужасен и не требует голосования против. Я думаю, что два небольших изменения улучшат его. Изменение 1 будет использоваться sizeof(input)вместо 100 при вызове cin.getline(); это означало бы, что вы можете изменить размер входного буфера, и вам нужно изменить только одну строку вместо двух. Изменение 2 будет заключаться в проверке возврата с cin.getline()помощью, например, if (!cin.getline(input, sizeof(input))) { ...handle EOF or error... }или чего-то подобного, чтобы напомнить OP, что операции ввода, в частности, уязвимы для неожиданного поведения. Это тоже нужно для других ответов.
— Джонатан Леффлер

221

Он не «терпит неудачу»; он просто перестает читать. Он видит лексический токен как «строку».

Использование std::getline:

int main()
{
   std::string name, title;

   std::cout << "Enter your name: ";
   std::getline(std::cin, name);

   std::cout << "Enter your favourite movie: ";
   std::getline(std::cin, title);

   std::cout << name << "'s favourite movie is " << title;
}

Обратите внимание, что это не то же самое std::istream::getline, что работает с charбуферами C-стиля, а не std::stringс.

Обновить

Ваш отредактированный вопрос мало похож на оригинал.

Вы пытались getlineвойти в intбуфер, а не в строку или символьный буфер. Операции форматирования потоков работают только с operator<<и operator>>. Либо используйте один из них (и соответствующим образом настройте для ввода нескольких слов), либо используйте getlineи лексически преобразуйте его intв постфактум.


2
Мне этот ответ нравится больше, чем принятый, потому что мне не нужно указывать длину символа.
— TheWanderer

1
@TheWanderer Действительно, это значительное преимущество.
— Гонки

Не забудьте включить sstream: #include <sstream>
— GilbertS

@LightnessRacesinOrbit, не могли бы вы помочь? Это дает мне лишнюю новую строку без всякой причины при печати вывода.
— Аншуман Кумар

@AnshumanKumar Я думаю, что getlineможет включать завершающую новую строку в строке, которую он возвращает. Если да, то вы должны удалить его.
— Марк Рэнсом,

41

Стандартная библиотека предоставляет функцию ввода с именем ws, которая использует пробелы из входного потока. Вы можете использовать это так:

std::string s;
std::getline(std::cin >> std::ws, s);

4
Я думаю, что это пока лучший ответ. Я могу объединить это с std :: cin >> выше.
— Андра

1
Лучший ответ на данный момент. При использовании std::getline(std::cin, s)я получал очень беспорядочный, и я бы сказал, прерывание ввода при ожидании ввода в цикле while/ for. Эта опция решила мою проблему!
— Златан Омерович

Включить sstream: #include <sstream>
— GilbertS

25

Использование:

getline(cin, input);

функцию можно найти в

#include <string>

3
+1 Это единственный ответ, который у меня действительно сработал. В остальных ответах говорится об использовании cin.getline (), но это просто дало мне сообщение об ошибке, что функция не существует.
— blembo

8
@blembo: Правда? Потому что мой ответ, опубликованный более чем за три года до этого, говорит то же самое (в отличие от того, что вы утверждаете).
— Lightness Races in Orbit

@blembo: А если cin.getlineего нет в вашей системе, значит, вы сделали что-то очень неправильно. Скорее всего, вы приводили неправильные аргументы. Лучше не обвинять других в своих ошибках ...
— Гонки

14

Вы хотите использовать функцию .getline в cin.

#include <iostream>
using namespace std;

int main () {
  char name[256], title[256];

  cout << "Enter your name: ";
  cin.getline (name,256);

  cout << "Enter your favourite movie: ";
  cin.getline (title,256);

  cout << name << "'s favourite movie is " << title;

  return 0;
}

Взял пример отсюда . Проверьте это для получения дополнительной информации и примеров.


12
Фактически, вы редко хотите использовать member- getline. Это устарело. getlineВместо этого используйте бесплатный , который можно использовать с std::string. [Кстати, cplusplus.com не является рекомендуемым ресурсом]
— Lightness Races in Orbit

2
@Tomalak Почему не рекомендуется использовать cplusplus.com? Я использую его все время: P
— лимон

6
@KevinDuke: Учебники могут вводить в заблуждение и неточны, а ссылка содержит множество ошибок. Это хорошие ресурсы.
— Гонки легкости на орбите

1
@NickSweeting: Ага; используйте это вместо этого.
— Lightness Races in Orbit

2
Что касается ссылок на документацию, cppreference.com является эффективной заменой cplusplus.com (оба являются неофициальными пересказами)
— Бен Фойгт

5

ПУТЬ C

Вы можете использовать getsфункцию из cstdio (stdio.h в c):

#include<cstdio>
int main(){

char name[256];
gets(name); // for input
puts(name);// for printing 
}

ПУТЬ С ++

gets удален в c ++ 11.

[Рекомендуется]: вы можете использовать getline (cin, name), который находится внутри, string.h или cin.getline (name, 256), который находится iostreamсам по себе.

#include<iostream>
#include<string>
using namespace std;
int main(){

char name1[256];
string name2;
cin.getline(name1,256); // for input
getline(cin,name2); // for input
cout<<name1<<"\n"<<name2;// for printing
}

10
Очень плохой совет, getsбезопасно пользоваться невозможно. Это даже было полностью удалено в C11.
— Мат,

1

Я предпочитаю использовать следующий метод для ввода данных:

#include <iostream>
#include <string>

using namespace std;

int main(void) {
    string name;

    cout << "Hello, Input your name please: ";
    getline(cin, name);

    return 0;
}

На самом деле это очень просто использовать, а не определять общую длину массива для строки, содержащей символ пробела.


1

Как прочитать строку из ввода?

Вы можете прочитать одно слово, завершенное пробелом, std::cinследующим образом:

#include<iostream>
#include<string>
using namespace std;

int main()
{
    cout << "Please enter a word:\n";

    string s;
    cin>>s;

    cout << "You entered " << s << '\n';
}

Обратите внимание, что нет явного управления памятью и буфера фиксированного размера, который может быть переполнен. Если вам действительно нужна целая строка (а не одно слово), вы можете сделать это:

#include<iostream>
#include<string>
using namespace std;

int main()
{
    cout << "Please enter a line:\n";

    string s;
    getline(cin,s);

    cout << "You entered " << s << '\n';
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.