2010-01-27 36 views
9

Tôi đang cố gắng sử dụng hoạt động an toàn trong việc xử lý đầu vào với số lượng chỉ trong C++, vì vậy tôi sử dụng một đối tượng stringstream như vậy:Vấn đề với tái sử dụng một đối tượng stringstream

#include <iostream> 
#include <string> 
#include <sstream> 
using namespace std; 

int main() 
{ 
    int first, second; 
    string input; 

    stringstream sstream; 

    cout << "First integer: "; 
    getline(cin, input); 
    sstream.str(input); 
    sstream >> first; 

    cout << first << endl; //display user input in integers 

    cout << "Second integer: "; 
    getline(cin, input); 
    sstream.str(input); 
    sstream >> second; 

    cout << second << endl; //display user input in integers 

    getline(cin, input); //pause program 

    return 0; 
} 

Tuy nhiên, lần thứ hai xung quanh nó dường như cung cấp cho biến 'thứ hai' một giá trị tùy ý. Đây là đầu ra:

First integer: 1 
1 
Second integer: 2 
2293592 

Nếu tôi khai báo hai đối tượng chuỗi và sử dụng chúng tương ứng cho cả hai biến, nó có vẻ hoạt động tốt. Điều này có nghĩa rằng tôi không thể tái sử dụng một đối tượng chuỗi trong cách tôi đang cố gắng làm? Trong chương trình thực sự của tôi, tôi có ý định xử lý nhiều hơn hai giá trị đầu vào từ người dùng, vì vậy tôi chỉ muốn đảm bảo nếu có một cách khác thay vì tạo ra nhiều đối tượng chuỗi. Tôi nghi ngờ nó có liên quan rất lớn nhưng tôi đang trên Windows XP và tôi đang sử dụng MinGW như trình biên dịch của tôi.

Tôi đánh giá rất cao sự giúp đỡ nào.

Trả lời

13

Sử dụng sstream.clear(); sau sstream >> first;.

+1

Chỉ cần những gì tôi đang tìm kiếm Tôi thích câu trả lời nhanh trên trang này – kaykun

4

Cách tốt hơn để thực hiện chuyển đổi này giữa các kiểu dữ liệu sẽ là sử dụng boost::lexical_cast.

Thông tin và ví dụ có thể được tìm thấy tại Boost Site.

Dưới đây là ví dụ về thực hiện chuyển đổi chuỗi int và ngược lại (chuỗi thành int) chẳng hạn như những gì bạn đang làm trong chương trình của mình.

#include <string> 
#include <boost/lexcal_cast.hpp> 

int main(int argc, char *argv[]) 
{ 
    int i = 42; 
    std::string s = boost::lexical_cast<std::string>(i); 
    int j = boost::lexical_cast<int>(s); 

    return 1; 
} 
+1

Hoặc, nếu OP không muốn sử dụng Boost, anh ta có thể viết diễn viên từ vựng của riêng mình trong khoảng năm dòng mã (xem http://www.gotw.ca/ ấn phẩm/mill19.htm) –

2
cout << "First integer: "; 
getline(cin, input); 
sstream.str(input); 
sstream >> first;  // state of sstream may be eof 

cout << "Second integer: "; 
getline(cin, input); 
sstream.str(input); 
sstream.clear();  // clear eof state 
sstream >> second; // input from sstream 
11

Bạn cần phải thiết lập lại trạng thái của stringstream. Nói chung, đây gồm hai bước: làm sạch bộ đệm:

sstream.str(""); 

và đặt lại các lỗi cờ trạng thái:

sstream.clear(); 

Nếu bạn không xóa bộ đệm, nếu bạn nhận được một đầu vào như "123abc" sau đó "abc" sẽ vẫn ở trong luồng khi bạn cố đọc từ đó trong lần tiếp theo.

Bạn cũng nên đảm bảo kiểm tra trạng thái lỗi của luồng (sstream.fail()) để đảm bảo rằng quá trình trích xuất thành công. Nếu bạn muốn chắc chắn rằng người dùng chỉ nhập một số nguyên (ví dụ, bạn muốn ngăn người dùng nhập vào, nói "123abc", thì bạn nên kiểm tra để đảm bảo sstream.eof() là đúng.

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