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.