std :: cin đầu vào có khoảng trắng?


144
#include <string>

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

Người dùng muốn vào "Hello World". Nhưng cinthất bại ở khoảng trống giữa hai từ. Làm thế nào tôi có thể thực cinhiện trong toàn bộ Hello World?

Tôi thực sự đang làm điều này với các cấu trúc và cin.getlinedường như không hoạt động. Đây là mã của tôi:

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

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

Điều này mang lại một lỗi. Có ý kiến ​​gì không?


27
Bạn không nên chỉnh sửa câu hỏi của mình để đặt câu hỏi mới như vậy. Lý do là mọi người đã đưa ra câu trả lời cho câu hỏi ban đầu của bạn và bây giờ những câu trả lời đó dường như nằm ngoài ngữ cảnh. Nếu câu hỏi ban đầu của bạn đã được trả lời, chỉ cần bắt đầu một câu hỏi mới để tránh nhầm lẫn.
Pete

Rõ ràng sau khi kiểm tra một chút, nhưng bạn có thể vui lòng thêm một khai báo cho biến libraryđể nó rõ ràng rằng nó thuộc loạicd
chandsie

Xin lỗi các bạn, điều này đã được thực hiện trong sự vội vàng, tôi sẽ đăng lại cái này.
chanh

1
Nếu bạn định đăng lại nó bằng cách thay thế, vui lòng gắn cờ câu hỏi để xóa bằng một mod.
Các cuộc đua Lightness trong quỹ đạo

2
Trong bản cập nhật của bạn, bạn đang cố gắng getlinevào một int. Tất nhiên là thất bại.
Ben Voigt

Câu trả lời:


102

Bạn phải sử dụng cin.getline():

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

7
@Kevin Meh, nó xảy ra. C ++ không chính xác như trực quan như chúng ta mong muốn.
Pete

61
Ew; Tại sao nên sử dụng char-buffers? Đó là năm 2011.
Cuộc đua nhẹ nhàng trong quỹ đạo

3
Và tại sao không sử dụng cin.getline(input, sizeof(input));? Ngoài ra, bạn không nên kiểm tra trạng thái trở lại?
Jonathan Leffler

2
@JonathanLeffler Tại thời điểm này được viết, đây là câu trả lời tôi có cho câu hỏi ban đầu (nhìn vào bình luận đầu tiên cho câu hỏi thực tế và bạn sẽ thấy bối cảnh đã thay đổi do chỉnh sửa bởi OP). Dù bằng cách nào, nếu bạn cảm thấy câu trả lời là khủng khiếp, hãy hạ nó xuống. Tôi thừa nhận rằng đây có thể không phải là giải pháp "tốt nhất" nhưng nó là một giải pháp không hơn không kém. Thay vì hỏi tại sao tôi không sử dụng thứ gì đó, bạn có thể nói với chúng tôi tất cả lý do tại sao chúng ta nên làm theo cách của bạn.
Pete

7
Câu trả lời của bạn không khủng khiếp và không cần hạ cấp. Tôi nghĩ rằng hai thay đổi nhỏ sẽ cải thiện nó. Thay đổi 1 sẽ sử dụng sizeof(input)thay cho 100 trong cuộc gọi đến cin.getline(); điều đó có nghĩa là bạn có thể thay đổi kích thước của bộ đệm đầu vào và chỉ cần thay đổi một dòng thay vì hai dòng. Thay đổi 2 sẽ là kiểm tra lợi nhuận từ cin.getline()bằng cách sử dụng, ví dụ, if (!cin.getline(input, sizeof(input))) { ...handle EOF or error... }hoặc một cái gì đó tương tự, để nhắc nhở OP rằng các hoạt động đầu vào, đặc biệt, dễ bị tổn thương trước hành vi không mong muốn. Những câu trả lời khác cũng cần điều này.
Jonathan Leffler

215

Nó không "thất bại"; nó chỉ dừng đọc Nó thấy một mã thông báo từ vựng là một "chuỗi".

Sử dụng 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;
}

Lưu ý rằng điều này không giống như std::istream::getline, hoạt động với charbộ đệm kiểu C thay vì std::strings.

Cập nhật

Câu hỏi được chỉnh sửa của bạn có chút giống với bản gốc.

Bạn đã cố gắng getlinevào một int, không phải là một bộ đệm chuỗi hoặc ký tự. Các hoạt động định dạng của luồng chỉ hoạt động với operator<<operator>>. Hoặc sử dụng một trong số chúng (và điều chỉnh phù hợp cho đầu vào nhiều từ), hoặc sử dụng getlinevà chuyển đổi từ vựng intsang thực tế.


2
Tôi thích câu trả lời này tốt hơn câu trả lời được chấp nhận, vì tôi không cần chỉ định độ dài ký tự.
TheWanderer

1
@TheWanderer Thật vậy, đó là một lợi ích đáng kể.
Các cuộc đua nhẹ nhàng trong quỹ đạo

Hãy nhớ bao gồm cả dòng: #include <
sux

@LightnessRacesinOrbit, bạn có thể vui lòng giúp đỡ không? Điều này cho tôi thêm một dòng mới mà không có lý do trong khi in đầu ra của tôi.
Anshuman Kumar

@AnshumanKumar Tôi nghĩ getlinecó thể bao gồm dòng mới kết thúc trong chuỗi mà nó trả về. Nếu vậy, tùy thuộc vào bạn để xóa nó.
Đánh dấu tiền chuộc

31

Thư viện chuẩn cung cấp một hàm đầu vào được gọi là wstiêu thụ khoảng trắng từ luồng đầu vào. Bạn có thể sử dụng nó như thế này:

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

4
Tôi nghĩ rằng đây là câu trả lời tốt nhất cho đến nay. Tôi có thể kết hợp điều này với std :: cin >> ở trên.
Andra

1
Câu trả lời tốt nhất cho đến nay. Khi sử dụng std::getline(std::cin, s)tôi sẽ nhận được rất lộn xộn và tôi sẽ nói, đầu vào bị gián đoạn khi chờ đầu vào trong một vòng lặp while/ for. Tùy chọn này đã giải quyết vấn đề của tôi!
omerowitz

Bao gồm dòng: #include <
sux

24

Sử dụng :

getline(cin, input);

chức năng có thể được tìm thấy trong

#include <string>

2
+1 Đây là câu trả lời duy nhất thực sự hiệu quả với tôi. Phần còn lại của câu trả lời là sử dụng cin.getline () nhưng điều đó chỉ gây ra lỗi cho tôi khi hàm không tồn tại.
blembo

7
@ Flagbo: Thật sao? Bởi vì câu trả lời của tôi, được đăng hơn ba năm trước bài này, nói chính xác điều tương tự (trái ngược với những gì bạn tuyên bố).
Các cuộc đua nhẹ nhàng trong quỹ đạo

@ Flagbo: Và nếu cin.getlinekhông tồn tại trên hệ thống của bạn, bạn đã làm điều gì đó rất sai. Nhiều khả năng bạn đã vượt qua các đối số sai. Tốt nhất đừng đổ lỗi cho người khác về lỗi lầm của bạn ...
Các cuộc đua nhẹ nhàng trong quỹ đạo

13

Bạn muốn sử dụng chức năng .getline trong 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;
}

Lấy ví dụ từ đây . Kiểm tra nó để biết thêm thông tin và ví dụ.


12
Trong thực tế, bạn hiếm khi muốn sử dụng thành viên- getline. Nó đã lỗi thời. Sử dụng miễn phí getlinethay thế, có thể được sử dụng với std::string. [BTW, cplusplus.com không phải là tài nguyên được đề xuất]
Các cuộc đua nhẹ nhàng trong quỹ đạo

1
@Tomalak Tại sao cplusplus.com không được đề xuất? Tôi sử dụng nó mọi lúc: P
chanh

6
@KevinDuke: Các hướng dẫn có thể sai lệch và không chính xác, và tài liệu tham khảo chứa vô số lỗi. Đây là những nguồn lực tốt.
Các cuộc đua nhẹ nhàng trong quỹ đạo

1
@NickSweeting: Vâng; sử dụng cái này thay thế
Các cuộc đua nhẹ nhàng trong quỹ đạo

1
Đối với các liên kết tài liệu, cppreference.com là một sự thay thế hiệu quả cho cplusplus.com (cả hai đều là paraph cụm từ không chính thức)
Ben Voigt

4

CÁCH C

Bạn có thể sử dụng getschức năng được tìm thấy trong cstdio (stdio.h trong c):

#include<cstdio>
int main(){

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

CÁCH C ++

gets được loại bỏ trong c ++ 11.

[Khuyến nghị]: Bạn có thể sử dụng getline (cin, name) trong string.h hoặc cin.getline (tên, 256) trong iostreamchính nó.

#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
Lời khuyên rất tệ, getslà không thể sử dụng một cách an toàn. Nó thậm chí đã được gỡ bỏ hoàn toàn trong C11.
Mat

1

Tôi thay vì sử dụng phương pháp sau để có được đầu vào:

#include <iostream>
#include <string>

using namespace std;

int main(void) {
    string name;

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

    return 0;
}

Nó thực sự rất dễ sử dụng thay vì xác định tổng chiều dài của mảng cho một chuỗi chứa ký tự khoảng trắng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.