2012-10-04 24 views
6

thể trùng lặp:
how do I validate user input as a double in C++?C++, làm thế nào để xác minh là dữ liệu đầu vào là các kiểu dữ liệu đúng

Tôi mới đến C++, và tôi có một chức năng trong đó tôi muốn người dùng nhập giá trị double. Làm thế nào tôi sẽ đi về bảo đảm rằng đầu vào giá trị là của datatype chính xác? Ngoài ra, lỗi sẽ được xử lý như thế nào? Hiện tại, tất cả những gì tôi có:

if(cin >> radius){}else{} 

Tôi sử dụng `try {} catch() {}, nhưng tôi nghĩ đó không phải là giải pháp phù hợp cho vấn đề này. Bất kỳ trợ giúp sẽ được đánh giá cao.

+4

Điều này hoạt động khá tốt: http://www.parashift.com/c++-faq/istream-and-ignore.html – chris

+1

đọc dưới dạng chuỗi và phân tích bằng cách sử dụng regex. – rplusg

Trả lời

13

Nếu ostream& operator>>(ostream& , T&) không khai thác dữ liệu được định dạng (chẳng hạn như số nguyên, đôi, phao, ...), stream.fail() sẽ là đúng và do đó !stream cũng sẽ được đánh giá là đúng.

Vì vậy, bạn có thể sử dụng

cin >> radius; 
if(!cin){ 
    cout << "Bad value!"; 
    cin.clear(); 
    cin.ignore(numeric_limits<streamsize>::max(), '\n'); 
    cin >> radius; 
} 

hoặc đơn giản là

while(!(cin >> radius)){ 
    cout << "Bad value!"; 
    cin.clear(); 
    cin.ignore(numeric_limits<streamsize>::max(), '\n'); 
} 

Điều quan trọng là ignore phần còn lại của dòng là, kể từ operator>> sẽ không trích xuất bất kỳ dữ liệu từ dòng nữa vì nó là ở định dạng sai. Vì vậy, nếu bạn xóa

cin.ignore(numeric_limits<streamsize>::max(), '\n'); 

vòng lặp của bạn sẽ không bao giờ kết thúc vì đầu vào không bị xóa khỏi đầu vào chuẩn.

Xem thêm:

+1

'sream.good()' có thể sai ngay cả khi đầu vào là chính xác. Và khi sử dụng luồng trong ngữ cảnh boolean, false là 'stream.fail()', và true là '! Stream.fail()'; 'stream.good()' không bao giờ thâm nhập vào nó. Bất kỳ tham chiếu nào đến 'istream :: good' liên quan đến vấn đề của người đăng là sai. –

+3

Tuyên bố của bạn rằng 'toán tử >>' sẽ không trích xuất bất kỳ dữ liệu nào từ luồng nếu dữ liệu đó không đúng định dạng cũng sai; nó có thể trích xuất _some_ của dữ liệu. (Hãy suy nghĩ của một đầu vào dọc theo dòng của "1,2e + x" '.Luồng chỉ đảm bảo một ký tự nhìn về phía trước và lỗi không thể được phát hiện cho đến khi ''x'' được nhìn thấy. Tất cả các ký tự trước đó sẽ được trích xuất.) –

+0

@JamesKanze: Tôi đã cố gắng quan tâm đến những lo ngại trong cả hai nhận xét của bạn, tuy nhiên, nó vẫn cảm thấy hơi vụng về. Tôi sẽ xem xét sau, nếu bạn tìm thấy bất kỳ sai lầm nào khác, vui lòng chỉnh sửa và để lại nhận xét. Nó luôn luôn tốt để tìm hiểu một cái gì đó mới :). – Zeta

3

Bạn cần đọc toàn bộ dòng bằng cách sử dụng std::getlinestd::string. Đó là cách để xác minh đầy đủ rằng toàn bộ dòng là của kiểu dữ liệu chính xác:

std::string line; 
while(std::getline(std::cin, line)) 
{ 
    std::stringstream ss(line); 
    if ((ss >> radius) && ss.eof()) 
    { 
     // Okay break out of loop 
     break; 
    } 
    else 
    { 
     // Error! 
     std::cout << "Invalid input" << std::endl; 
    } 
} 
0

Ví dụ này là tự giải thích, tuy nhiên với phương pháp này bạn không thể phân biệt giữa int và double.

int main() 
{ 
    double number = 0; 

    if (!(std::cin >> number)) 
    { 
    std::cout << "That's not a number; "; 
    } 
    else 
    { 
    std::cout << "That's a number; "; 
    } 
} 
+2

Uhm Vì vậy, nếu họ nhập, nói, 0? Hoặc là điều này sẽ không làm việc với phần ints .. – StarWind0

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