C++數值與字串相互轉換的那些事(一)字串轉數值(轉載請註明)
以前一門心思搞演算法,這個東西覺得自己寫個函式就能實現的事,但是到了公司後才發現同事寫的程式碼裡面,呼叫各種庫函式、window API、流來實現。什麼都不懂的我表示鴨梨很大,今天翻了翻資料瞭解了下各種方法的使用方法、區別以及適用範圍,寫成了這篇又長又臭又沒條理的東西。
注:以下字串均特指空終止的字串(字串以'\0‘(一個位元組的0)結束,寬字串(本文中指UTF-8不涉及UTF-16及其他)以‘\0’(兩個位元組的0))
1.字串轉換為數值
1.1使用現成c庫函式將10進位制字串轉換為數值(c庫函式不提供其他進位制轉換)
所屬標頭檔案<cstdlib>
atoi()、_wtoi()、atol()、_wtol()、atof()、_wtol()、_atoi64()、_wtoi64(),_w打頭為相應寬字元版本不逐一介紹。
atoi()函式原型如下,將字串轉換為int型別
int atoi( const char *string);
_wtoi()函式原型如下,將寬字串轉換為int型別
int _wtoi(const wchar_t *);
atol()函式原型如下,將字串轉化為long
atof()函式原型如下,將字串轉化為doulbelong atol(const char *);
double atof(const char *);
_atoi64()函式原型如下,將字串轉化為__int64(long long int)例如:__int64 _atoi64(const char *);
輸出結果:#include <windows.h> #include <iostream> #include <cstdlib> using namespace std; int main() { char szBuff[100]="1000.2121"; int iTest = 0; double dTest = 0.0; long lTest = 0; __int64 i64Test = 0; iTest = atoi(szBuff); dTest = atof(szBuff); lTest = atol(szBuff); i64Test = _atoi64(szBuff); printf("iTest = %d\n",iTest); printf("lTest = %ld\n",lTest); printf("dTest = %lf\n",dTest); printf("i64Test = %I64d\n",i64Test); return 0; }
1.2使用現成Windows API將字串轉換為數值(Windows API 不提供浮點型別的轉換,不支援64位整數)iTest = 1000 lTest = 1000 dTest = 1000.212100 i64Test = 1000
1.2.1使用現成Windows API將10進位制字串轉換為數值
所屬標頭檔案<shlwapi.h>
注:使用時注意引入"shlwapi.lib"
StrToInt()(Widows一個相容的函式,當定義了UNICODE時表示StrToIntW,否則表示StrToIntA,以下不一一列舉)、StrToLong
StrToInt()函式原型如下,將字串轉換為int(以下均一ANSI字串為例,UNICODE不再列舉)
StrToLong()函式原型如下,將字串轉換為long(其實Windows 32位機器int和long沒區別)int StrToIntA(LPCSTR lpSrc);
1.2.1使用現成Windows API將10或者16進位制字串轉換為數值(不支援浮點型別,不支援64位整數)#define StrToLong StrToInt
所屬標頭檔案<shlwapi.h>
注:使用時注意引入"shlwapi.lib"
StrToIntEx。(注:無StrToLongEx)
StrToIntEx函式原型如下,將任意進位制字串轉換為int型別,轉換成功返回TRUE,否則為FALSE
第一個引數表示待轉換的字串,第二個字串用來表示待轉換的字串是16進位制還是10進位制,當dwFlags為STIF_DEFAULT表示10進位制,當dwFlags為BOOL StrToIntExA(LPCSTR pszString, DWORD dwFlags, int FAR * piRet);
STIF_SUPPORT_HEX時表示10進位制。第三個引數代表一個指向int的指標(指向轉換後的值)
例如:
#include <windows.h> #include <iostream> #include <cstdlib> #include <shlwapi.h> using namespace std; #pragma comment(lib,"shlwapi.lib") int main() { int value; char szHex[100] = "0xFF"; StrToIntExA(szHex,STIF_SUPPORT_HEX,&value); printf("%d\n",value); return 0; }
輸出結果為:255
1.3使用流將字串轉換為數值(64位流操作不支援,支援10進位制,16進位制,8進位制)以ANSI為例
所屬標頭檔案<sstream>
預定義以下巨集
#define MY_OCT 1 //8進位制 #define MY_DEC 2 //10進位制 #define MY_HEX 3 //16進位制
通過自定義函式來說明:myStrToIntExA()、myStrToLongExA()、myStrToDoubleA()。(double型別僅支援10進位制)
myStrToIntExA()函式如下,將字串轉int
int myStrToIntExA(char *s,const int &iFlags = MY_DEC) { int num; stringstream ss(s); switch (iFlags) { case MY_OCT: ss>>std::oct>>num;//8進位制 break; case MY_DEC: ss>>std::dec>>num;//10 break; case MY_HEX: ss>>std::hex>>num; break; default: break; } return num; }
myStrToLongExA()函式如下,將字串轉long
myStrToDoubleA()函式如下,將字串轉doublelong myStrToLongExA(char *s,const int &iFlags = MY_DEC) { long num; stringstream ss(s); switch (iFlags) { case MY_OCT: ss>>std::oct>>num;//8進位制 break; case MY_DEC: ss>>std::dec>>num;//10 break; case MY_HEX: ss>>std::hex>>num; break; default: break; } return num; }
double myStrToDoulbeA(char *s) { double num; stringstream ss(s); ss>>num; return num; }
例如:#include <sstream> #include <iostream> using namespace std; #define MY_OCT 1 //8進位制 #define MY_DEC 2 //10進位制 #define MY_HEX 3 //16進位制 int myStrToIntExA(char *s,const int &iFlags = MY_DEC) { int num; stringstream ss(s); switch (iFlags) { case MY_OCT: ss>>std::oct>>num;//8進位制 break; case MY_DEC: ss>>std::dec>>num;//10 break; case MY_HEX: ss>>std::hex>>num; break; default: break; } return num; } double myStrToDoulbeA(char *s) { double num; stringstream ss(s); ss>>num; return num; } long myStrToLongExA(char *s,const int &iFlags = MY_DEC) { long num; stringstream ss(s); switch (iFlags) { case MY_OCT: ss>>std::oct>>num;//8進位制 break; case MY_DEC: ss>>std::dec>>num;//10 break; case MY_HEX: ss>>std::hex>>num; break; default: break; } return num; } int main() { char str[] = "11"; int iTest = myStrToIntExA(str,MY_HEX); long lTest = myStrToLongExA(str,MY_HEX); double dTest = myStrToDoulbeA(str); printf("%d\n",iTest); printf("%ld\n",lTest); printf("%lf\n",dTest); return 0; }
輸出結果:17 17 11.000000
3種方法的優劣如下表所示
64位整數 浮點數 2進位制 寬字元 8進位制 10進位制 16進位制 特點 庫函式 支援 支援 不支援 支援 不支援 支援 不支援 效率高 windows API 不支援 不支援 不支援 支援 不支援 支援 支援 效率較高 流 不支援 僅支援10進位制 不支援 支援 支援 支援 支援 效率較低 總體來說
庫函式唯一支援64位整數,效率高,
windows API 相容性好,效率較高
流 支援進位制多且支援10進位制浮點轉換,但是效率不高。
如果想支援非10進位制的64位整數和浮點數,只能乖乖自己實現了,建議用第一種方式進行進位制轉換就OK了