#include <stdlib.h> int atoi(const char *nptr); double atof(const char *nptr); 返回值:轉換結果
atoi
把一個字元串開頭可以識別成十進制整數的部分轉換成int
型,相當於下面要講的strtol(nptr, (char **) NULL, 10);
。例如atoi("123abc")
的返回值是123,字元串開頭可以有若干空格,例如atoi(" -90.6-")
的返回值是-90。如果字元串開頭沒有可識別的整數,例如atoi("asdf")
,則返回0,而atoi("0***")
也返回0,根據返回值並不能區分這兩種情況,所以使用atoi
函數不能檢查出錯的情況。下面要講的strtol
函數可以設置errno
,因此可以檢查出錯的情況,在嚴格的場合下應該用strtol
,而atoi
用起來更簡便,所以也很常用。
atof
把一個字元串開頭可以識別成浮點數的部分轉換成double
型,相當於下面要講的strtod(nptr, (char **) NULL);
。字元串開頭可以識別的浮點數格式和C語言的浮點數常量相同,例如atof("31.4 ")
的返回值是31.4,atof("3.14e+1AB")
的返回值也是31.4。atof
也不能檢查出錯的情況,而strtod
可以。
#include <stdlib.h> long int strtol(const char *nptr, char **endptr, int base); double strtod(const char *nptr, char **endptr); 返回值:轉換結果,出錯時設置errno
strtol
是atoi
的增強版,主要體現在這幾方面:
不僅可以識別十進制整數,還可以識別其它進制的整數,取決於base
參數,比如strtol("0XDEADbeE~~", NULL, 16)
返回0xdeadbee的值,strtol("0777~~", NULL, 8)
返回0777的值。
endptr
是一個傳出參數,函數返回時指向後面未被識別的第一個字元。例如char *pos; strtol("123abc", &pos, 10);
,strtol
返回123,pos
指向字元串中的字母a。如果字元串開頭沒有可識別的整數,例如char *pos; strtol("ABCabc", &pos, 10);
,則strtol
返回0,pos
指向字元串開頭,可以據此判斷這種出錯的情況,而這是atoi
處理不了的。
如果字元串中的整數值超出long int
的表示範圍(上溢或下溢),則strtol
返回它所能表示的最大(或最小)整數,並設置errno
為ERANGE
,例如strtol("0XDEADbeef~~", NULL, 16)
返回0x7fffffff並設置errno
為ERANGE
。
回想一下使用fopen
的套路if ( (fp = fopen(...)) == NULL) { 讀取errno }
,fopen
在出錯時會返回NULL
,因此我們知道需要讀errno
,但strtol
在成功調用時也可能返回0x7fffffff,我們如何知道需要讀errno
呢?最嚴謹的做法是首先把errno
置0,再調用strtol
,再查看errno
是否變成了錯誤碼。Man Page上有一個很好的例子:
例 25.10. strtol的出錯處理
#include <stdlib.h> #include <limits.h> #include <stdio.h> #include <errno.h> int main(int argc, char *argv[]) { int base; char *endptr, *str; long val; if (argc < 2) { fprintf(stderr, "Usage: %s str [base]\n", argv[0]); exit(EXIT_FAILURE); } str = argv[1]; base = (argc > 2) ? atoi(argv[2]) : 10; errno = 0; /* To distinguish success/failure after call */ val = strtol(str, &endptr, base); /* Check for various possible errors */ if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN)) || (errno != 0 && val == 0)) { perror("strtol"); exit(EXIT_FAILURE); } if (endptr == str) { fprintf(stderr, "No digits were found\n"); exit(EXIT_FAILURE); } /* If we got here, strtol() successfully parsed a number */ printf("strtol() returned %ld\n", val); if (*endptr != '\0') /* Not necessarily an error... */ printf("Further characters after number: %s\n", endptr); exit(EXIT_SUCCESS); }
strtod
是atof
的增強版,增強的功能和strtol
類似。