2007年9月24日 星期一

[C++]isNumeric

C / C++ 的標準函式庫裡,找不到一個類似 VB 裡的 isNumeric() 可以判斷字串是否為數值型式的標準函式可用。

沒錯, Visual C++ 的 System 命名空間裡,有 Char::isNumeric 可以用,但是非 VC++ 的 compiler 不能用。

另外,有找到一份 C++ Programming How-To ,裡面有一份強化過的 A! Dev's String class ,看起來遠比標準 C++ 的 String class 好多了,有空應該研究看看。只是學生比賽時,這樣的程式庫不知道可不可以用?

回到 isNumeric() 函式,看來只有自己手工打造一個來用了。


google 了很多資料後,在 C / C++ Help這裡,看到 jaro 提供的方法:使用 strtod() 函式來判斷,似乎是個最好的解法了。於是參考 jaro 的方法,修改了一下,寫出了下面的 isNumeric() 函式:


 
my isNumeric function

bool isNumeric( const char *);
bool isNumeric( const string &);

bool isNumeric( const char *test)
// 接受傳統 C 字串引數,判所是否為數值字串
// 若是,則傳回 true ;若否,則傳回 false
{
char *testEnd; // 指向 strtod() 後剩於部份的開頭
double d;

d=strtod (test, &testEnd);
// 如果轉換後 testEnd 指向 test 字串開頭,
// 則表示沒有轉換出任何數值,也就是說 test 是字串,不是數值
return test!=testEnd;
}

bool isNumeric( const string &test)
// 接受 C++ 字串物件引數,判所是否為數值字串
// 若是,則傳回 true ;若否,則傳回 false
// 因為在 C++ 的程式裡, string 類別比 char 陣列好用
// 所以寫了個 string 類別物件引數的版本
{
char *testEnd;
double d;

d=strtod (test.c_str ( ), &testEnd);
return test.c_str ( )!=testEnd;
}


 

以下是測試程式:


 
測試 isNumeric() 函式

#include <iostream>
#include <string>
#include <sstream>
#include <cctype>

using namespace std;

bool isNumeric( const char *);
bool isNumeric( const string &);

void main( )
{
istringstream iss( "this is a book 3607252 3.14159632587425 -45265" );

//char test[80]="";
string test;

while ( iss >> test ) {
if ( isNumeric(test) )
cout << "得到數字:" << atof (test.c_str ( ) ) << endl;
else
cout << "得到字串:" << test << endl;
}
system ( "pause" );
}

bool isNumeric( const char *test)
{
char *testEnd;
double d;

d=strtod (test, &testEnd);
return test!=testEnd;
}

bool isNumeric( const string &test)
{
char *testEnd;
double d;

d=strtod (test.c_str ( ), &testEnd);
return test.c_str ( )!=testEnd;
}


 

然後是輸出結果如下,看來蠻管用的。

得到字串:this
得到字串:is
得到字串:a
得到字串:book
得到數字:3.60725e+006
得到數字:3.1416
得到數字:-45265

沒有留言:

張貼留言