在C++(gcc)中是否有相當於TryParse的?在C++(gcc)中是否有TryParse等價物?
我想解析一個字符串,它可能包含(+31321)並將其存儲爲長。我知道電話號碼存儲爲字符串和字符串匹配,但爲了我的需要,我想將它們存儲很長時間,有時它們可能包含加號(+)。什麼會解析它在C++?
在C++(gcc)中是否有相當於TryParse的?在C++(gcc)中是否有TryParse等價物?
我想解析一個字符串,它可能包含(+31321)並將其存儲爲長。我知道電話號碼存儲爲字符串和字符串匹配,但爲了我的需要,我想將它們存儲很長時間,有時它們可能包含加號(+)。什麼會解析它在C++?
strtoul()和家人的問題沒有真正的方法來測試失敗。
如果解析失敗,則返回0而不設置errno(僅在溢出時設置)。
提升詞彙投
#include <boost/lexical_cast.hpp>
int main()
{
try
{
long x = boost::lexical_cast<long>("+1234");
std::cout << "X is " << x << "\n";
}
catch(...)
{
std::cout << "Failed\n";
}
}
使用流
int main()
{
try
{
std::stringstream stream("+1234");
long x;
char test;
if ((!(stream >> x)) || (stream >> test))
{
// You should test that the stream into x worked.
// You should also test that there is nothing left in the stream
// Above: if (stream >> test) is good then there was content left after the long
// This is an indication that the value you were parsing is not a number.
throw std::runtime_error("Failed");
}
std::cout << "X is " << x << "\n";
}
catch(...)
{
std::cout << "Failed\n";
}
}
做它用scanf函數:
int main()
{
try
{
char integer[] = "+1234";
long x;
int len;
if (sscanf(integer, "%ld%n", &x, &len) != 1 || (len != strlen(integer)))
{
// Check the scanf worked.
// Also check the scanf() read everything from the string.
// If there was anything left it indicates a failure.
throw std::runtime_error("Failed");
}
std::cout << "X is " << x << "\n";
}
catch(...)
{
std::cout << "Failed\n";
}
}
很好的答案,但應該更好地明確地捕獲異常,而不是使用'...',對嗎? – tenfour 2011-12-25 20:58:44
@tenfour:絕對。我只是以此爲例。 – 2011-12-25 22:43:11
+31321
可以使用通常的流提取操作符解析爲long
。
#include <iostream>
#include <sstream>
int main()
{
std::istringstream s("+31321");
long n;
s >> n;
std::cout << n << '\n';
}
儘管解析的實際電話號碼(括號,破折號,擴展等)可能不是那麼簡單。
輸入提取操作符>>(我希望它是一個可接受的名稱)適用並返回一個流&,它有一個bool操作符,意味着提取已成功嘗試。例如,從Cubbi回答:
...
std::istringstream s("+31321");
long n;
if (s >> n)
std::cout << n << '\n';
....
這將成功,當然,考慮到s的適當內容。
有點不同(更簡單但不是類型安全),scanf家族也有C++中的實用工具。當然,你可以寫的例子是這樣的:
...
long n;
if (sscanf("+31321", "%d", &n) == 1)
std::cout << n << '\n';
...
正則表達式的一個子集,使這個功能相當強大:比如匹配逗號separed左空間多領域的微調:
if (sscanf("a,b,c", " [^,], [^,], [^,]", a,b,c) == 3) ...
事實上,在將字符串轉換爲數字之前,數字應該「標準化」爲通用格式。這需要刪除所有符號,並用適當的表示法替換它們。
但是,您必須非常在意將字符串表示爲電話號碼(即非數字:它們不受常規算術運算):以一個或多個零開頭的數字與刪除零的數字不同:
00是+的典型替代品,但前面沒有00(或+)的數字應以00c爲前綴,其中c是國家代碼。
在轉換之前,您需要做一些預處理以獲得統一的字符串表示形式,否則您將面臨「別名」不同的事情。
見http://www.cplusplus.com/reference/clibrary/cstdlib/strtoul/ – tenfour 2011-12-25 20:08:12
strtoul()的問題是沒有指示失敗(它只是返回0)。 – 2011-12-25 20:57:49