Anh tôi gần đây đã bắt đầu học C++. Ông nói với tôi một vấn đề ông gặp phải trong khi cố gắng để xác nhận đầu vào trong một chương trình đơn giản. Anh ta có một menu văn bản nơi người dùng nhập một số nguyên choice
, nếu họ đã nhập một lựa chọn không hợp lệ, họ sẽ được yêu cầu nhập lại nó (làm trong khi vòng lặp). Tuy nhiên, nếu người dùng nhập một chuỗi thay vì một int, mã sẽ phá vỡ. tôi đọc câu hỏi khác nhau trên stackoverflow và nói với ông phải viết lại mã của mình dọc theo dòng:Cách tốt nhất để thực hiện xác thực đầu vào trong C++ bằng cin là gì?
#include<iostream>
using namespace std;
int main()
{
int a;
do
{
cout<<"\nEnter a number:"
cin>>a;
if(cin.fail())
{
//Clear the fail state.
cin.clear();
//Ignore the rest of the wrong user input, till the end of the line.
cin.ignore(std::numeric_limits<std::streamsize>::max(),\
'\n');
}
}while(true);
return 0;
}
Trong khi điều này làm việc ok, tôi cũng thử một vài ý tưởng khác:
1. Sử dụng một khối try catch. Nó không hoạt động. Tôi nghĩ rằng điều này là bởi vì một ngoại lệ không được nâng lên do đầu vào xấu. 2. Tôi đã thử if(! cin){//Do Something}
không hoạt động. Tôi chưa tìm ra cái này.
3. Thứ ba, tôi đã thử nhập một chuỗi có độ dài cố định và sau đó phân tích nó. Tôi sẽ sử dụng atoi(). Tiêu chuẩn này có tuân thủ và di động không? Tôi có nên viết chức năng phân tích cú pháp của riêng mình không?
4. Nếu viết một lớp sử dụng cin, nhưng tự động thực hiện loại phát hiện lỗi này, có lẽ bằng cách xác định loại biến đầu vào khi chạy, nó có quá nhiều chi phí không? Thậm chí có thể không?
Tôi muốn biết cách tốt nhất để thực hiện loại kiểm tra này, phương pháp hay nhất là gì?
Tôi muốn thêm rằng trong khi tôi không phải là người mới viết mã C++, tôi mới viết mã tuân thủ tiêu chuẩn tốt. Tôi đang cố gắng để không học những thực hành xấu và học những điều đúng. Tôi sẽ có nhiều nghĩa vụ nếu người trả lời đưa ra một lời giải thích chi tiết.
EDIT: Tôi thấy rằng litb đã trả lời một trong các chỉnh sửa trước đó của tôi. Tôi sẽ đăng mã đó ở đây để tham khảo.
#include<iostream>
using namespace std;
int main()
{
int a;
bool inputCompletionFlag = true;
do
{
cout<<"\nEnter a number:"
cin>>a;
if(cin.fail())
{
//Clear the fail state.
cin.clear();
//Ignore the rest of the wrong user input, till the end of the line.
cin.ignore(std::numeric_limits<std::streamsize>::max(),\
'\n');
}
else
{
inputCompletionFlag = false;
}
}while(!inputCompletionFlag);
return 0;
}
Mã này không thành công như "1asdsdf". Tôi không biết làm thế nào để sửa chữa nó nhưng litb đã đăng một câu trả lời tuyệt vời. :)
Cảm ơn lời giải thích chi tiết, nhưng tôi đã tra cứu và thấy rằng Boost không phải là thư viện chuẩn. Trong ánh sáng đó, sẽ tốt hơn nếu tôi cuộn mã của riêng mình nếu tôi có thể hoặc tôi nên gắn bó với tăng cường? – batbrat
Tôi chỉ nhận thấy rằng nó sẽ được chuẩn hóa ở mức độ lớn trong C++ 0x. Vì vậy, tôi sẽ sử dụng Boost. Tôi sẽ rất vui nếu bạn xác nhận. Cảm ơn. – batbrat
vâng, tiếp theo C++ sẽ bao gồm một số thư viện được thiết kế sau khi tăng cường (shared_ptr, thread, system (error_code, ...), array, bind, function). nhưng không phải date_time. Tuy nhiên, khuyến khích được khuyến khích. nó tốt hơn là lăn của riêng bạn thực sự –