2011-12-25 29 views
1

在C++(gcc)中是否有相當於TryParse的?在C++(gcc)中是否有TryParse等價物?

我想解析一個字符串,它可能包含(+31321)並將其存儲爲長。我知道電話號碼存儲爲字符串和字符串匹配,但爲了我的需要,我想將它們存儲很長時間,有時它們可​​能包含加號(+)。什麼會解析它在C++?

+1

見http://www.cplusplus.com/reference/clibrary/cstdlib/strtoul/ – tenfour 2011-12-25 20:08:12

+1

strtoul()的問題是沒有指示失敗(它只是返回0)。 – 2011-12-25 20:57:49

回答

3

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"; 
    } 
} 
+0

很好的答案,但應該更好地明確地捕獲異常,而不是使用'...',對嗎? – tenfour 2011-12-25 20:58:44

+0

@tenfour:絕對。我只是以此爲例。 – 2011-12-25 22:43:11

2

+31321可以使用通常的流提取操作符解析爲long

#include <iostream> 
#include <sstream> 
int main() 
{ 
    std::istringstream s("+31321"); 
    long n; 
    s >> n; 
    std::cout << n << '\n'; 
} 

演示:http://ideone.com/4rmlp

儘管解析的實際電話號碼(括號,破折號,擴展等)可能不是那麼簡單。

1

輸入提取操作符>>(我希望它是一個可接受的名稱)適用並返回一個流&,它有一個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) ... 
2

事實上,在將字符串轉換爲數字之前,數字應該「標準化」爲通用格式。這需要刪除所有符號,並用適當的表示法替換它們。

但是,您必須非常在意將字符串表示爲電話號碼(即非數字:它們不受常規算術運算):以一個或多個零開頭的數字與刪除零的數字不同:

00是+的典型替代品,但前面沒有00(或+)的數字應以00c爲前綴,其中c是國家代碼。

在轉換之前,您需要做一些預處理以獲得統一的字符串表示形式,否則您將面臨「別名」不同的事情。

相關問題