2009-06-23 39 views
24

Tôi có một vấn đề mà sscanf giải quyết (giải nén mọi thứ từ một chuỗi). Tôi không thích sscanf mặc dù nó không an toàn và cũ kỹ và khủng khiếp. Tôi muốn được thông minh và sử dụng một số bộ phận hiện đại hơn của thư viện chuẩn C++. Tôi nên sử dụng cái gì?Tôi nên sử dụng cái gì thay vì sscanf?

+2

Tại sao cố gắng để được "thông minh"? –

+11

Ví dụ với lý do ông nói, sscanf đó không an toàn. – jalf

+5

@Kaleb Pederson: Đối với nhiều người nói tiếng Anh, "thông minh" có thể chỉ có nghĩa là "thông minh" và không có ý nghĩa tiêu cực đôi khi có ở Hoa Kỳ. Lưu ý rằng Ben Hymers đến từ Vương quốc Anh. – Naaff

Trả lời

36

Tôi nghĩ rằng các câu trả lời khác bị thiếu điểm. Câu hỏi không phải là về I/O, đó là về trích xuất dữ liệu từ một chuỗi.

Hãy thử stringstream:

#include <sstream> 

... 

std::stringstream s("123 456 789"); 
int a, b, c; 
s >> a >> b >> c; 
+0

làm thế nào để biết nếu c không có, ví dụ chuỗi là "123 456"? – unludo

+0

@unludo: Trong trường hợp đó, 'c' sẽ không được sửa đổi. Bạn có thể khởi tạo 'c' với một giá trị mặc định, hoặc bạn có thể cần phân tích phức tạp hơn. Một tokenizer có lẽ sẽ làm việc. –

+1

Kể từ C++ 11, 'c' sẽ được đặt lại thành' 0' và trước đó tôi tin rằng giá trị sau thất bại của nó là không xác định. Dù sao, để kiểm tra xem 'c' có sử dụng trạng thái luồng (để thuận tiện không, từ' toán tử bool() '):' if (s >> a >> b) nếu (s >> c) abc_there(); else ab_there(); else didnt_have_a_and_b(); '. –

-1

fgets hoặc strtol

2

Nếu bạn bao gồm sstream bạn sẽ có quyền truy cập vào các lớp stringstream mà cung cấp dòng cho các chuỗi, đó là những gì bạn cần. Roguewave có một số tốt examples on how to use it.

5

Đối với hầu hết các công việc dòng tiêu chuẩn thực hiện công việc một cách hoàn hảo,

std::string data = "AraK 22 4.0"; 
std::stringstream convertor(data); 
std::string name; 
int age; 
double gpa; 

convertor >> name >> age >> gpa; 

if(convertor.fail() == true) 
{ 
    // if the data string is not well-formatted do what ever you want here 
} 

Nếu bạn cần các công cụ mạnh hơn cho phân tích cú pháp phức tạp hơn, sau đó bạn có thể xem xét Regex hoặc thậm chí Thần từ Boost.

0

Nếu bạn thực sự không muốn sử dụng luồng (Rất tốt vì dễ đọc), bạn có thể sử dụng StringPrintf.

Bạn có thể tìm thấy việc thực hiện nó trong Folly:

https://github.com/facebook/folly/blob/master/folly/String.h#L165

+0

Đoạn mã nhỏ (Tôi đang sử dụng một cái gì đó gần như giống nhau), mặc dù nó là một thay thế cho 'printf' thay vì' sscanf'. –

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