std :: cin введення з пробілами?


144
#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. Звичайно, це не вдається.
Ben Voigt

Відповіді:


102

Ви повинні використовувати cin.getline():

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

7
@ Кевін Мех, буває. C ++ не настільки інтуїтивно зрозумілий, як ми хотіли б.
Піт

62
Ew; навіщо використовувати char-буфери? Це 2011.
Легкі перегони на орбіті

3
А чому б не використовувати cin.getline(input, sizeof(input));? Також не варто перевіряти стан повернення?
Джонатан Леффлер

2
@JonathanLeffler У той час, коли це було написано, це була відповідь, яку я отримав на запитання, яке було задано спочатку (подивіться перший коментар до фактичного питання, і ви побачите, що контекст змінився через редагування ОП). У будь-якому випадку, якщо ви відчуваєте, що відповідь така жахлива, негативно скажіть її. Я визнаю, що це може бути не найкращим рішенням, але це рішення не менш. Замість того, щоб запитати, чому я щось не використав, ви можете нам сказати, чому ми повинні робити це так, як ви.
Піт

7
Ваша відповідь не страшна і не потребує зворотного звороту. Я думаю, що дві невеликі зміни покращать її. Зміна 1 використовуватиме sizeof(input)замість 100 у виклику до cin.getline(); це означатиме, що ви можете змінити розмір буфера введення, і вам потрібно змінити лише один рядок замість двох рядків. Зміною 2 було б перевірити повернення cin.getline(), використовуючи, наприклад, if (!cin.getline(input, sizeof(input))) { ...handle EOF or error... }чи щось подібне, щоб нагадати ОП про те, що операції введення, зокрема, вразливі до несподіваної поведінки. Інші відповіді також потребують цього.
Джонатан Леффлер

215

Він не "провалюється"; він просто перестає читати. Він бачить лексичний маркер як "рядок".

Використання 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буферами у стилі С, а не з std::strings.

Оновлення

Ваше відредаговане запитання мало нагадує оригінал.

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


2
Мені подобається ця відповідь набагато краще, ніж прийнята, тому що мені не потрібно вказувати довжину символів.
TheWanderer

1
@TheWanderer Дійсно, це суттєва перевага.
Гонки легкості на орбіті

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

@LightnessRacesinOrbit, чи можете ви допомогти? Це дає мені додатковий новий рядок без жодної причини під час друку мого результату.
Аншуман Кумар

@AnshumanKumar Я думаю, що getlineможе включати завершальний новий рядок у рядок, який він повертає. Якщо це так, ви вирішите видалити його.
Марк Викуп

31

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

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

4
Я думаю, що це найкраща відповідь поки що. Я можу поєднати це з std :: cin >> вище.
Андра

1
Найкраща відповідь поки що. Під час використання std::getline(std::cin, s)я отримав би дуже брудний і, я б сказав, перерваний вхід під час очікування введення в while/ forциклі. Цей варіант вирішив мою проблему!
omerowitz

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

24

Використання:

getline(cin, input);

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

#include <string>

2
+1 Це єдина відповідь, яка насправді працювала на мене. В решті відповідей йдеться про використання cin.getline (), але це просто дало мені помилку, сказавши, що функція не існує.
блембо

7
@blembo: Дійсно? Тому що моя відповідь, опублікована за три роки до цього, говорить саме те саме (на відміну від того, що ви стверджуєте, що воно говорить).
Гонки легкості на орбіті

@blembo: І якщо cin.getlineу вашій системі не існує, ви зробили щось дуже неправильно. Швидше за все, ви передавали неправильні аргументи. Краще не звинувачувати інших у своїх помилках ...
Гонки легкості в орбіті

13

Ви хочете використовувати .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. [BTW, cplusplus.com не є рекомендованим ресурсом]
Гонки легкості на орбіті

1
@Tomalak Чому cplusplus.com не рекомендується? Я використовую його весь час: P
лимон

6
@KevinDuke: Підручники можуть бути оманливими та неточними, а посилання містить безліч помилок. Це хороші ресурси.
Гонки легкості на орбіті

1
@NickSweeting: Так; використовувати це замість цього.
Гонки легкості на орбіті

1
Для посилань на документацію cppreference.com є ефективною заміною для cplusplus.com (обидва є неофіційними парафразами)
Ben Voigt

4

C ШЛЯХ

Ви можете використовувати getsфункцію, знайдену в cstdio (stdio.h in c):

#include<cstdio>
int main(){

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

ШЛЯХ С ++

gets видаляється в c ++ 11.

[Рекомендовано]: Ви можете використовувати getline (cin, ім'я), яка знаходиться в, string.h або cin.getline (ім'я, 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використовувати її безпечно неможливо. Його навіть повністю видалили в С11.
мат

1

Я скоріше використовую наступний метод, щоб отримати вхід:

#include <iostream>
#include <string>

using namespace std;

int main(void) {
    string name;

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

    return 0;
}

Насправді це дуже просто у використанні, а не визначення загальної довжини масиву для рядка, який містить пробільний символ.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.