2012-07-12 22 views
9

Tôi đã đoạn mã sau:Issue với cin khi không gian được nhập, sử dụng chuỗi lớp

main.cpp

#include <iostream> 
#include <string> 

using namespace std; 

string name; 
string age; 

int main() { 
    cout <<"Name: "; 
    cin >> name; 
    cout << endl; 
    cout <<"Age: "; 
    cin >> age; 
    cout << endl; 
    cout << "Your name is " << name << ", and you are " << age << " years old." << endl; 
    cout << "Press enter to close this application" << endl; 
    getchar(); 
    return 0; 
} 

tôi nhận thấy rằng nếu tôi đặt một không gian ở đầu vào của tôi cho tên đó nó đã giành không cho tôi một cơ hội để nhập tên, và nó sẽ xem các mục nhập sau khi không gian như tuổi tác. Tôi xin lỗi nếu đây là một lỗi newbie, mà nó có thể là. Trước đây tôi đã lập trình Java và quyết định tôi muốn chuyển sang C++ vì nó phù hợp hơn với nhu cầu của tôi. Tôi cũng có thể định dạng mã của tôi lạ với các tiêu chuẩn của bạn, xin vui lòng sửa nó nếu bạn muốn.

Screenshot of console

Tôi cũng đã nhận thấy lỗi khác, điều mà tôi không bao giờ thực sự có vấn đề gì với trong Java. Tôi không thể tìm ra cách ngăn chặn nó ngay lập tức đóng cửa khi nó kết thúc quá trình xử lý. Tôi đã nghe nói bạn có thể sử dụng "hệ thống. (" Tạm dừng "), nhưng tôi cũng đã được nói không sử dụng nó.Tôi thực sự bối rối về những gì để sử dụng.Tôi đã nghe sử dụng getchar() ;, nhưng nó dường như không làm gì cả.

Bất kỳ trợ giúp sẽ được đánh giá rất nhiều, như tôi là một người mới bắt đầu hoàn tất khi nói đến C++.

+0

@chris Tôi muốn chọn nhận xét của bạn làm câu trả lời nhưng tôi thực sự không nghĩ nó sẽ cho tôi. Cảm ơn sự giúp đỡ của bạn. Bạn có nhớ đăng lại hay cái gì đó như một câu trả lời để tôi có thể chọn nó? –

+0

Tôi đã quyết định trước nhận xét của bạn để đưa ra câu trả lời chi tiết hơn. Nó ở đó (và hy vọng không có những sai lầm tinh tế) nếu bạn muốn đọc nó. – chris

+0

Ồ, và lý do 'getchar' của bạn không hoạt động là lý do tương tự ví dụ đầu tiên của tôi để thay thế' system ("pause") 'không hoạt động. Nó được giải thích trong câu trả lời. – chris

Trả lời

13

Dưới đây là những gì đang xảy ra với bộ đệm đầu vào khi bạn chạy của bạn chương trình:

std::cin >> name; 

Bạn đang đợi nhập liệu. Khi bạn nhập "Ryan Cleary", và nhấn Enter, bộ đệm đầu vào bao gồm:

Ryan Cleary\n 

Bây giờ cin của bạn đọc đầu vào như bình thường, dừng lại ở khoảng trắng, để lại bộ đệm của bạn như thế này:

Cleary\n 

Note không gian bắt đầu, vì nó dừng lại sau khi đọc Ryan. Biến đầu tiên của bạn hiện có chứa Ryan. Tuy nhiên, nếu bạn muốn tên đầy đủ, hãy sử dụng std::getline. Nó sẽ đọc cho đến khi một dòng mới, không chỉ khoảng trắng. Dù sao, tiếp tục trên:

std::cin >> age; 

Bây giờ bạn sẽ nhận được một đầu vào khác. Mặc dù đã có thứ gì đó ở đó. Nó bỏ qua khoảng trắng cho đến khi nó có thể bắt đầu đọc, để lại bộ đệm chỉ với:

\n 

Biến thứ hai của bạn nhận được văn bản Cleary. Lưu ý dòng mới vẫn còn trong bộ đệm, mang đến cho tôi phần thứ hai. Thay thế system ("pause"); theo cách luôn hoạt động là khó khăn.Tốt nhất thường là sống với một giải pháp ít hơn hoàn hảo, hoặc như tôi muốn làm, người ta không được đảm bảo để thực hiện chính xác những gì nó nói:

std::cin.get(); //this consumes the left over newline and exits without waiting 

Được rồi, vì vậy cin.get() không công việc. Làm thế nào về điều này:

std::cin.get(); //consume left over newline 
std::cin.get(); //wait 

Điều đó hoạt động hoàn hảo, nhưng điều gì sẽ xảy ra nếu bạn sao chép-dán vào nơi không còn dòng mới? Bạn sẽ phải nhấn enter hai lần!

Giải pháp là xóa dòng mới (và bất kỳ thứ gì khác) ra, và sau đó đợi. Đây là mục đích của cin.sync(). Tuy nhiên, như đã thấy trong phần ghi chú, nó không được bảo đảm để xóa bộ đệm như nó nói, vì vậy nếu trình biên dịch của bạn chọn không, nó không thể được sử dụng. Đối với tôi, tuy nhiên, nó không chính xác điều đó, để lại một giải pháp:

std::cin.sync(); //clear buffer 
std::cin.get(); //wait 

Điều xấu chính về system("pause"); là bạn không có ý tưởng những gì chương trình nó sẽ chạy trên máy tính của người khác. Họ có thể đã thay đổi pause.exe hoặc đặt một trong đó được tìm thấy đầu tiên, và bạn không có cách nào để biết. Điều này có thể làm hỏng máy tính của họ do có thể là bất kỳ chương trình nào.

+1

Cảm ơn bạn, một câu trả lời tuyệt vời. Nó giải thích rất nhiều cho tôi. Tôi có nhiều sự hiểu biết hơn trước với cách phân tích cú pháp cin của C++. –

+0

Tôi gặp vấn đề này trong khi Googling. Một lời giải thích tuyệt vời. Cảm ơn v. Nhiều. – PingPing

7

Bạn nên cố gắng cin.getline, theo cách đó, con suối sẽ đọc cho đến khi ký tự dòng mới đầu tiên

Ok, lời khuyên xấu như một số người đã chỉ ra. Bạn có thể sử dụng std::getline để đọc toàn bộ dòng. 210, bạn có thể vượt qua nó như là tham số đầu tiên (và chuỗi là thứ hai).

std::string str; 
std::getline(cin, str); // to read until the end of line 

std::getline(cin, str, ' '); // to read until a space character, for instance 

(tất nhiên, bạn có thể bỏ qua phần std:: từ các dòng, vì bạn đã thông báo cho trình biên dịch mà bạn đang sử dụng std namespace)

+0

-1 lời khuyên không tốt. 'std :: getline' an toàn và dễ dàng,' cin.getline' thì không. –

+0

Tôi đã bỏ lỡ phần OP nói anh ta đang sử dụng lớp chuỗi. –

+0

Đã sửa. Nhưng dù sao, tôi cũng không xứng đáng với những người bình chọn như tôi vừa mượn câu trả lời từ những bình luận ... –

Các vấn đề liên quan