bool isNumeric(string s){
if ( !s.empty() && s[0] != '-' )
s = "0" + s; //prepend 0
string garbage;
stringstream ss(s);
ss >> *(auto_ptr<double>(new double)) >> garbage;
/*
//the line above extracts the number into an anonymous variable. it could also be done like this:
double x;
ss >> x >> garbage;
*/
//if there is no garbage return true or else return false
return garbage.empty();
}
làm thế nào nó hoạt động:
chuỗi dòng >> quá tải có thể chuyển đổi chuỗi thành các loại số học khác nhau bằng cách đọc các ký tự liên tục từ chuỗi (ss trong trường hợp này) cho đến khi hết ký tự HOẶC ký tự tiếp theo không đáp ứng tiêu chí được lưu trữ vào loại biến đích.
ví dụ 1:
stringstream ss("11");
double my_number;
ss >> my_number; //my number = 11
ví dụ2:
stringstream ss("011");
double my_number;
ss >> my_number; //my number = 11
ví dụ 3:
stringstream ss("11ABCD");
double my_number;
ss >> my_number; //my number = 11 (even though there are letters after the 11)
giải thích biến "rác":
Tại sao không kiểm tra xem trích xuất vào đôi của tôi có giá trị hợp lệ không và sau đó trả về true nếu có?
chú ý example3 ở trên vẫn sẽ đọc thành công số 11 vào biến my_number ngay cả khi chuỗi đầu vào là "11ABCD" (không phải là số).
để xử lý trường hợp này, chúng ta có thể thực hiện một trích xuất khác thành một biến chuỗi (mà tôi đặt tên là rác) có thể đọc bất cứ thứ gì có thể còn sót lại trong bộ đệm chuỗi sau khi trích xuất ban đầu thành biến kiểu kép. Nếu bất cứ thứ gì còn sót lại, nó sẽ được đọc thành "rác", có nghĩa là toàn bộ chuỗi được truyền vào không phải là một số (nó chỉ bắt đầu bằng một). trong trường hợp này chúng tôi muốn trả về false;
phần giải thích "0" được thêm vào:
cố gắng trích xuất một ký tự thành một nhân đôi sẽ thất bại (trả về 0 thành gấp đôi của chúng ta) nhưng vẫn sẽ di chuyển vị trí bộ đệm chuỗi sang sau ký tự. Trong trường hợp này, phần đọc rác của chúng ta sẽ trống, điều này sẽ khiến hàm trả về không đúng. để giải quyết vấn đề này, tôi đã thêm 0 vào chuỗi để nếu ví dụ chuỗi được truyền vào là "a" thì nó được đổi thành "0a" để 0 sẽ được trích xuất thành gấp đôi và "a" được trích xuất thành rác.
nhập trước 0 sẽ không ảnh hưởng đến giá trị của số nên số vẫn sẽ được trích xuất chính xác vào biến kép của chúng tôi.
if (expr) return true; return false;
! Chỉ cần viếtreturn expr;
.