C Primer Plus 第11章 11.9 把字符串轉換爲數字

數字即能以字符串形式也能 以數字形式存儲。以字符串形式存儲數字就是存儲數字字符。例如,數字213即能以數字'2'、‘1’、‘3’、‘\0’的形式存儲在一個字符串數組中。以數字形式存儲213意味着把字存儲爲 一個int數值。對於數字運算C要求數字形式。可是在屏幕上顯示數字卻要求字符串形式,這是由於屏幕顯示的字符。printf()和sprintf()函數經過%d或其餘說明符把數字形式轉換爲字符串形式或者相反。C還有一些函數專門用於把字符串形式轉換爲數字形式。
假如,您想編寫一個使用數字命令程序。很不巧的是,命令行參數是以字符串形式被讀取的。所以,要想使用數字值,就必須先把字符串轉換爲數字。若是數字是個整數,那就可使用atoi()(表明alphanumeric to integer)。atoi()函數以字符串爲參數,返回相應的整數值。
程序清單11.28 hello.c程序
 數組

/*hello.c  把命令行參數轉換成數字*/
#include <stdio.h>
#include <stdlib.h>

int main(int argc,char *argv[])
{
    int i,times;

    if(argc<2 || (times = atoi(argv[1]))<1)
        printf("Usage: %s positive-number\n",argv[0]);
    else
    for(i=0;i<times;i++)
        puts("Hello,good looking!");
    
    return 0;
}

下面是一個運行示例:
% hello 3
Hello,good looking!
Hello,good looking!
Hello,good looking!
%是UNIX提示符。命令行參數3以字符串"3\0"的形式存放。atoi()函數把這個字符串轉換爲整數3.而後把3賦給times。這樣就決定了for循環執行的次數。函數

若是運行程序時沒有提供命令行參數,argc<2判斷就會中斷程序並給出一個提示信息。若是times爲0或爲負,也會發生一樣的狀況。C的邏輯運算符的運算順序確保:若是argc<2,就再也不運算atoi(argv[1])。ui

若是字符串只是以一個整數開頭,atoi()函數仍然能夠工做。這種狀況下,atoi()函數遇到非整數部分以前一直轉換字符。例如,atoi("42regular")返回整數42。若是命令行相似hello what,又會出現什麼狀況呢?在咱們使用的C的實現上,若是參數不能識別爲數字,atoi()函數返回一個0值。但ANSI標準規定,上述狀況下的行爲是未定義的。稍後咱們將介紹strtol()函數能夠提供更可靠的錯誤檢測。atom

咱們包含了stdlib.h頭文件,這是由於在ANSI中這個文件包含了atoi()函數的聲明。此外,這個頭文件還包含了atof()和atol()函數的聲明。atof()函數把一個字符串轉換爲double類型的值,atol()函數則把字符串轉換爲long類型的值。它們的做用和atoi()相似,所以分別爲double和long類型。命令行

ANSI C 提供了這些函數的更復雜版本:strtol()、strtoul()和strtod()。其中,strtol()函數把一個字符串轉換爲long值,strtoul()把一個字符串轉換爲unsigned long型值,strtod()函數把一個字符串轉換爲double型值。這些函數的複雜性在於它們還能夠識別並報告字符串中非數字部分的第一個字符。strtol()和strtoul()函數還容許您指定數字的基數。指針

下面看一個涉及strtol()函數的例子。函數原型以下:code

long strtol(const char *nptr, char **endptr, int base);字符串

在這裏,nptr是一個指向您但願轉換的字符串的指針endptr是指向標誌輸入數字的結束字符的指針的地址,base是數字的基數。get

程序清單 11.29 strcnvt.c程序原型

/*strcnvt.c  嘗試使用strtol()函數*/
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    char number[30];
    char *end;
    long value;

    puts("Enter a number(empty line to quit): ");
    while(gets(number) && number[0]!='\0')
    {
        value=strtol(number,&end,10);
        printf("value:%ld, stopped at %s(%d) \n",
               value,end,*end);
        value=strtol(number,&end,16);  /*基於16*/
        printf("value:%ld, stopped at %s(%d) \n",
               value,end,*end);
        puts("Next number: ");
    }
    puts("Bye!\n");

    return 0;
}

下面是一些輸出示例:
Enter a number(empty line to quit):
10
value:10, stopped at (0)
value:16, stopped at (0)
Next number:
10atom
value:10, stopped at atom(97)
value:266, stopped at tom(116)
Next number:
    
Bye!

首先請注意:若是基數是10,字符串「10」就被轉換爲10;若是基數是16,字符串」10「就被轉換爲16。還要注意,若是end指向一個字符,那麼*end就是一個字符。所以,第一次轉換在遇到空字符時結束,這樣end就指向空字符。若是輸出end,會顯示一個空字符,若是用%d格式輸出*end,就會顯示空字符的ASCII 碼。

對於輸入的第二個字符串(以10爲基數進行解釋),end是'a'字符的地址所以,輸出end顯示的是字符串"atom"輸出*end顯示的則是'a'字符的ASCII碼。可是,若是基數是16,'a'字符就會被識別爲一個有效的十六進制數字,函數會把16進制10a轉換爲十進制的266。

strtol()函數最多能夠有三十六進制,使用一直到'z'的字母做爲數字。strtoul()函數也同樣,但它轉換的是無符號值。strtod()函數只按照十進制進行轉換,所以它只使用兩個參數。

不少實現中都使用itoa()和ftoa()函數把整點和浮點數轉換爲字符串。可是這兩個函數並非ANSI C庫裏的函數;若是要求兼容性更好,可使用sprintf()函數來完成這些功能 。

相關文章
相關標籤/搜索