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);
dev gr
источник
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
}
abe312
источник
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';
}
Сборка завершена
источник