天天看點

C++:字元串與數字之間的互相轉換C++字元串,數字互相轉換

在C/C++語言中沒有專門的字元串變量,通常用字元數組來存放字元串。字元串是以“\0”作為結束符。C/C++提供了豐富的字元串處理函數,下面列出了幾個最常用的函數。

  ● 字元串輸出函數puts。

  ● 字元串輸出函數gets。

  ● 字元串連接配接函數strcat。

  ● 字元串複制函數strcpy。

  ● 測字元串長度函數strlen。

字元串是面試的重點考查部分的相關知識,通過考查字元串的相關知識可以考察程式員的程式設計規範以及程式設計習慣。并且其中包括了許多知識點,例如記憶體越界、指針與數組操作等。許多公司在面試時會要求應聘者寫一段複制字元串或字元串子串操作的程式。本章列舉了一些與字元串相關的面試題,有些題目要求較高的程式設計技巧。

6.1  數字與字元串的轉化

應聘時經常出現數字與字元串之間轉化的問題,面試官通過這類題目來考察應聘者能力,例如是否熟悉常用的庫函數,是否了解ASCII碼以及是否了解字元串的存儲格式等。

6.1.1  數字轉化為字元串

面試例題1:使用庫函數将數字轉換為字元串。

考點:C庫函數中數字轉換為字元串的使用。

出現頻率:★★★

解析

C語言提供了幾個标準庫函數,可以将任意類型(整型、長整型、浮點型等)的數字轉換為字元串,下面列舉了各函數的方法及其說明。

  ● itoa():将整型值轉換為字元串。

  ● ltoa():将長整型值轉換為字元串。

  ● ultoa():将無符号長整型值轉換為字元串。

  ● gcvt():将浮點型數轉換為字元串,取四舍五入。

  ● ecvt():将雙精度浮點型值轉換為字元串,轉換結果中不包含十進制小數點。

  ● fcvt():指定位數為轉換精度,其餘同ecvt()。

還可以使用sprintf系列函數把數字轉換成字元串,其比itoa()系列函數運作速度慢。下列程式示範了如何使用itoa()函數和gcvt()函數:

1    # include <stdio.h>

2    # include <stdlib.h>

3   

4    int main ()

5    {

6        int num_int = 435;

7        double num_double = 435.10f;

8        char str_int[30];

9        char str_double[30];

10  

11       itoa(num_int, str_int, 10);  //把整數num_int轉成字元串str_int

12       gcvt(num_double, 8, str_double);  //把浮點數num_double轉成字元串str_double

13  

14       printf("str_int: %s\n", str_int);

15       printf("str_double: %s\n", str_double);

16  

17       return 0;

18   }

程式輸出結果:

1    str_int: 435

2    str_double: 435.10001

  ● 代碼第11行中的參數10表示按十進制類型進行轉換,轉換後的結果是“435”,如果按二進制類型進行轉換,則結果為“1101110011”。

  ● 代碼第12行中的參數8表示精确位數,這裡得到的結果是“435.10001”。

答案

可以使用atoi系列函數把數字轉換成字元串。

面試例題2:不使用庫函數将整數轉換為字元串。

考點:數字轉換為字元串,了解相關ASCII碼。

出現頻率:★★★★

解析

如果不使用atoi或sprintf等庫函數,可以通過把整數的各位上的數字加“0”轉換成char類型并存到字元數組中。但是要注意,需要采用字元串逆序的方法。如以下程式所示:

1    #include <iostream>

2    using namespace std;

3   

4    void int2str(int n, char *str)

5    {

6        char buf[10] = "";

7        int i = 0;

8        int len = 0;

9        int temp = n < 0 ? -n: n;  // temp為n的絕對值

10  

11       if (str == NULL)

12       {

13           return;

14       }

15       while(temp)

16       {

17           buf[i++] = (temp % 10) + '0';  //把temp的每一位上的數存入buf

18           temp = temp / 10;

19       }

20  

21       len = n < 0 ? ++i: i;  //如果n是負數,則多需要一位來存儲負号

22       str[i] = 0;            //末尾是結束符0

23       while(1)

24       {

25           i--;

26           if (buf[len-i-1] ==0)

27           {

28               break;

29           }

30           str[i] = buf[len-i-1];  //把buf數組裡的字元拷到字元串

31       }

32       if (i == 0 )

33       {

34           str[i] = '-';          //如果是負數,添加一個負号

35       }

36   }

37  

38   int main()

39   {

40       int nNum;

41       char p[10];

42  

43       cout << "Please input an integer:";

44       cin >> nNum;

45       cout << "output: " ;

46       int2str(nNum, p);        //整型轉換成字元串

47       cout<< p << endl;

48  

49       return 0;

50   }

程式中的int2str函數完成了int類型到字元串類型的轉換。在代碼第46行對int2str函數做了測試。程式的執行結果如下所示:

Please input an integer: 1234

Output: 1234

如果輸入的是個負數,程式執行結果如下所示:

Please input an integer: -1234

Output: -1234

接下來對int2str函數的實作進行分析。

  ● 代碼第9行,把參數n的絕對值賦給temp,以後在計算各個位的整數時用temp,這樣保證在負數情況下取餘不會出現問題。

  ● 代碼第11~第14行判斷str的有效性,str不為NULL。

  ● 代碼第15~第19行的while循環中,将n的各個位存放到局部數組buf中,存放的順序與整數順序相反。例如n為整數123 456,while循環結束後buf應為“654 321”。

  ● 代碼第21行計算轉換後字元串的長度len,如果是負數,長度應該再加1。

  ● 代碼第22~第31行把數組buf中的非0元素逆向複制到參數str指向的記憶體中,如果n是負數,則str指向的第一個記憶體存放負号。

6.1.2  字元串轉化為數字

面試例題3:使用庫函數将字元串轉換為數字。

考點:C庫函數中字元串轉換為數字的使用。

出現頻率:★★★★

解析

與上節數字轉換為字元串類似,C/C++語言提供了幾個标準庫函數,可以将字元串轉換為任意類型(整型、長整型、浮點型等)。以下列舉了各函數的方法及其說明。

  ● atof():将字元串轉換為雙精度浮點型值。

  ● atoi():将字元串轉換為整型值。

  ● atol():将字元串轉換為長整型值。

  ● strtod():将字元串轉換為雙精度浮點型值,并報告不能被轉換的所有剩餘數字。

  ● strtol():将字元串轉換為長整值,并報告不能被轉換的所有剩餘數字。

  ● strtoul():将字元串轉換為無符号長整型值,并報告不能被轉換的所有剩餘數字。

以下程式示範如何使用atoi ()函數和atof ()函數。

1    # include <stdio.h>

2    # include <stdlib.h>

3   

4    int main ()

5    {

6        int num_int;

7        double num_double;

8        char str_int[30] = "435";         //将要被轉換為整型的字元串

9        char str_double[30] = "436.55";  //将要被轉換為浮點型的字元串

10  

11       num_int = atoi(str_int);          //轉換為整型值

12       num_double = atof(str_double);  //轉換為浮點型值

13  

14       printf("num_int: %d\n", num_int);

15       printf("num_double: %lf\n", num_double);

16  

17       return 0;

18   }

輸出結果:

num_int: 435

num_double: 436.550000

面試例題4:不使用庫函數将字元串轉換為數字。

考點:字元串轉換為數字時,對相關ASCII碼的了解。

出現頻率:★★★★

解析

程式代碼如下:

1    #include <iostream>

2    using namespace std;

3   

4    int str2int(const char *str)

5    {

6        int temp = 0;

7        const char *ptr = str;  //ptr儲存str字元串開頭

8   

9        if (*str == '-' || *str == '+')  //如果第一個字元是正負号,

10       {                      //則移到下一個字元

11           str++;

12       }

13       while(*str != 0)

14       {

15           if ((*str < '0') || (*str > '9'))  //如果目前字元不是數字

16           {                       //則退出循環

17               break;

18           }

19           temp = temp * 10 + (*str - '0'); //如果目前字元是數字則計算數值

20           str++;      //移到下一個字元

21       }   

22       if (*ptr == '-')     //如果字元串是以“-”開頭,則轉換成其相反數

23       {

24           temp = -temp;

25       }

26  

27       return temp;

28   }

29  

30   int main()

31   {

32       int n = 0;   

33       char p[10] = "";

34  

35       cin.getline(p, 20);   //從終端擷取一個字元串

36       n = str2int(p);      //把字元串轉換成整型數

37       

38       cout << n << endl;

39  

40       return 0;

41   }

程式執行結果:

輸入:1234

輸出:1234

輸入:-1234

輸出:-1234

輸入:+1234

輸出:1234

程式中的str2int函數作用是将字元串轉換成整數。這個函數的轉換過程與例題2中的int2str函數相比更加簡單,它隻需要做一次while循環(代碼第13行)就能把數值大小計算出來,如果結果是負數,就加一個負号。

C++字元串,數字互相轉換

一.将CString轉為CTime的幾種方法

CString   timestr   =   "2000年04月05日";  

  int   a,b,c   ;  

  sscanf(timestr.GetBuffer(timestr.GetLength()),"%d年%d月%d日",&a,&b,&c);  

  CTime   time(a,b,c,0,0,0);    

--------or - ---------------------

 CString   s("2001-8-29   19:06:23");  

  int   nYear,   nMonth,   nDate,   nHour,   nMin,   nSec;  

  sscanf(s,   "%d-%d-%d   %d:%d:%d",   &nYear,   &nMonth,   &nDate,   &nHour,   &nMin,   &nSec);  

  CTime   t(nYear,   nMonth,   nDate,   nHour,   nMin,   nSec);

---- or ------------------------

CString   timestr   =   "2000年04月05日";  

  int   year,month,day;  

  BYTE   tt[5];  

  //get   year  

  memset(tt,   0,   sizeof(tt));  

  tt[0]   =   timestr[0];  

  tt[1]   =   timestr[1];  

  tt[2]   =   timestr[2];  

  tt[3]   =   timestr[3];  

  year=   atoi((char   *)tt);  

  //get   month  

  memset(tt,   0,   sizeof(tt));  

  tt[0]   =   timestr[6];  

  tt[1]   =   timestr[7];  

  month   =   atoi((char   *)tt);  

  //get   day  

  memset(tt,   0,   sizeof(tt));  

  tt[0]   =   timestr[10];  

  tt[1]   =   timestr[11];  

  CTime   time(year,month,day,0,0,0);

從上面來看,很明顯使用sscanf()函數的優勢.

二.将CTIme轉換為CString的方法:

CTime  tmSCan = CTime::GetCurrentTime();

CString szTime = tmScan.Format("'%Y-%m-%d %H:%M:%S'");

這樣得到的日期時間字元串就是以"2006-11-27 23:30:59"的格式.這是不是很友善呢?

 //取得CTime中的日期

 CString cstrDate = tmScan.Format("%Y-%m-%d");

 //取得CTime中的時間

 CString cstrTime = tmScan.Format("%H:%M-%S");

          sprintf還有個不錯的表妹:strftime,專門用于格式化時間字元串的,用法跟她表哥很像,也是一大堆格式控制符,隻是畢竟小姑娘家心細,她還要調用者指定緩沖區的最大長度,可能是為了在出現問題時可以推卸責任吧。這裡舉個例子:

 更多更好的sprintf()函數說明參考:《spirntf,你知道多少?》

http://blog.csdn.net/steedhorse/archive/2005/03/25/330206.aspx

time_t t = time(0);

      //産生"YYYY-MM-DD hh:mm:ss"格式的字元串。

char s[32];

strftime(s, sizeof(s), "%Y-%m-%d %H:%M:%S", localtime(&t));

sprintf在MFC中也能找到他的知音:CString::Format,strftime在MFC中自然也有她的同道:CTime::Format,這一對由于從面向對象哪裡得到了贊助,用以寫出的代碼更覺優雅。

三,字元串轉換為數值類型

将字元串"20.0E6"轉換為數字

1,sscanf("20.0e5","%d",&x);

2,atof("20.0E6");

許多人用atoi(), atof() 和這個“家族”中的其它函數. 它們友善應用,但是有一個重要的缺點:

在轉換失敗和轉換字元串"0"時都傳回0, 這樣使得一緻性錯誤檢查變得幾乎不可能。 為了完整性我們給出了小段代碼:

代碼:

--------------------------------------------------------------------------------

   const char* str_int = "777";

   const char* str_float = "333.3";

   int i = atoi(str_int);

   float f = atof(str_float);

--------------------------------------------------------------------------------

一個更好的辦法:

更有一點複雜, 更遺一緻的辦法是利用sscanf()

代碼:

--------------------------------------------------------------------------------

   const char* str_int = "777";

   const char* str_float = "333.3";

   int i;

   float f;

   if(EOF == sscanf(str_int, "%d", &i)){

      //錯誤

   }

   if(EOF == sscanf(str_float, "%f", &f)){

      //錯誤

   }

--------------------------------------------------------------------------------

Since sscanf() takes a const char* parameter, you can directly use a CString with it:

因為sscanf()用const char* 作為參數, 是以你可以直接用CString作參數:

代碼:

--------------------------------------------------------------------------------

   CString str_int("777");

   if(EOF == sscanf(str_int, "%d", &i)){

      //error

   }

--------------------------------------------------------------------------------

小心格式描述符(如本例中的"%d")。 sscanf()沒有辦法檢查格式描述符與傳遞變量的類型比對與否。如果不比對你将得到不可預期的結果。 同樣注意sscanf()可以一次從字元串中提取一個或多個數值。 詳細資訊請查閱MSDN。

C++ 方法

如下的例子展示了利用标準C++類的來完成這個任務的模闆函數

代碼:

--------------------------------------------------------------------------------

#include <string>

#include <sstream>

#include <iostream>

template <class T>

bool from_string(T &t,

                 const std::string &s,

                 std::ios_base & (*f)(std::ios_base&))

{

   std::istringstream iss(s);

   return !(iss>>f>>t).fail();

}

int main()

{

   int i;

   float f;

   // from_string()的第三個參數應為如下中的一個

   // one of std::hex, std::dec 或 std::oct

   if(from_string<int>(i, std::string("ff"), std::hex)){

      std::cout<<i<<std::endl;

   }

   else{

      std::cout<<"from_string failed"<<std::endl;

   }

   if(from_string<float>(f,

                               std::string("123.456"),

                               std::dec))

   {

      std::cout<<f<<std::endl;

   }

   else{

      std::cout<<"from_string failed"<<std::endl;

   }

   return 0;

}

四, int char * float and CString Covernt

1。 int <->CString

1) int ->CString

int n = 1;

CString str;

str.Format("%d",n);

2) CString->int

CString str = "1";

int n = atoi(str.GetBuffer(0));

2. char* 與CString

1)char*->CString

char sz[128];

CString str;

str.Format("%s",sz);

2) CString -> char*

CString str;

//int nLength = str.GetLength();

char* sz = str.GetBuffer(0);

3. float<->CString

1)float->CString

float f = 0.0;

CString str;

str.Format("%f",f);

2) CString->float

CString str = "0.0";

float f = atof(str.GetBuffer(0));

c++ c