2011-05-30 34 views
45

我已經習慣於strtod和變種。 我想知道爲什麼沒有strtoi附帶stdlib.h。 爲什麼整數不在這個派對之外?爲什麼stdlib.h中沒有strtoi?

具體而言,我問爲什麼沒有atoi的版本與strtod的安全功能。

+0

有人啓發請標記strtoi – Eli 2011-05-30 22:58:44

+0

在落實,glibc的,例如,還具有安全功能'INT的atoi(爲const char * NPTR){回報(INT)與strtol(NPTR, (char **)NULL,10);}'不應該使用'atoi'' – yuan 2013-02-04 07:56:15

回答

43

strtol()將字符串轉換爲整數,長整數,但整數不過。有atoi()但它應該避免在大多數情況下,由於它缺乏錯誤報告機制無效輸入。

+1

當'long'的範圍超出'int'範圍時,'strtol()'不會在'int'上設置'errno'並且不返回'INT_MIN/MAX',只會溢出否定該安全特性的值。 – chux 2015-12-12 17:40:09

+3

@chux不知道你想說什麼。當然,如果傳遞的值超出了int的範圍,那不是一個錯誤。 – Wiz 2015-12-20 01:01:02

+0

由於答案並未詳細說明如何在嘗試轉換爲int時使用'strtol()',指出代表'int'範圍之外的值的字符串(但不是'long')不會設置'errno'也沒有有限的價值。這與表示'long'範圍之外的值的字符串不同:它會設置'errno'並獲得有限的值。 – chux 2015-12-20 02:44:20

-2

它叫atoi。有關詳細信息,請參閱Wikipedia,其中包括其繼任者strol

+7

。 – 2011-05-30 23:02:44

+2

@James McNellis _atoi不應該被使用_ - 你已經做出了這樣的表述,就好像你的理由應該是顯而易見的,但是幾個答案似乎都認爲atoi()是正確的解決方案,它不一定是那麼明顯。你想讓所有人都知道你爲什麼不應該使用atoi或者最好留下一個謎團嗎? – mah 2011-05-30 23:07:50

+0

@mah:如果'atoi'返回'0','INT_MIN'或'INT_MAX',則無法知道轉換是否成功。 – 2011-05-30 23:11:04

5

整數不被排除在派對之外:有strtol,它將字符串轉換爲long,這是一個整數類型。

0

SEE ALSO 
     atof(3), atoi(3), atol(3), strtol(3), strtoul(3) 

您正在尋找atoi(3)不要忽視您的聯機手冊的SEE ALSO部分:)。 :)

+1

其實我不是。對不起,我會澄清我的問題。 – Eli 2011-05-30 23:09:52

+0

@itsmyown,對澄清問題的+1 +1謝謝 – sarnold 2011-05-30 23:15:44

+0

嗯,我知道這是舊的,但是 - 'strto [u] l(3)'在'還有'中被提及! – 2012-12-10 15:00:35

2

這就是我一直在使用的。

long long_val; 
int int_value; 

errno = 0; 
long_val = strtol (theString, NULL, 10); 
if (errno) 
    handle_error; 
if ((long) someIntMin < long_val || long_val > (long) someIntMax) 
    handle_invalid; 
int_value = (int) long_val; 
+0

'if((long)someIntMin chux 2017-04-20 15:55:32

13

爲什麼會出現在stdlib.h中沒有strtoi?

在早期的C,還有比long不是一個標準符號類型更寬和更窄的所有轉換可以由strtol()製成 - 按以下步驟進行。

國際海事組織,這些和他們的unsigned對口現在缺少C函數和當前標準C庫中的設計缺點。


在許多系統中,longint具有相同的範圍,因此有單獨的strtoi()需要減小。此外,atoi()滿足快速和髒代碼的需要,但可能缺少錯誤檢測。也沒有strto_short()strto_signchar()

這是很容易創建一個替代strtoi()。簡化存在。

#include <errno.h> 
#include <limits.h> 
#include <stdlib.h> 

static long strto_subrange(const char *s, char **endptr, int base, 
    long min, long max) { 
    long y = strtol(s, endptr, base); 
    if (y > max) { 
    errno = ERANGE; 
    return max; 
    } 
    if (y < min) { 
    errno = ERANGE; 
    return min; 
    } 
    return y; 
} 

// OP's goal 
int strtoi(const char *s, char **endptr, int base) { 
    #if INT_MAX == LONG_MAX && INT_MIN == LONG_MIN 
    return (int) strtol(s, endptr, base); 
    #else 
    return (int) strto_subrange(s, endptr, base, INT_MIN, INT_MAX); 
    #endif 
} 

short strtoshort(const char *s, char **endptr, int base) { 
    return (short) strto_subrange(s, endptr, base, SHRT_MIN, SHRT_MAX); 
} 

signed char strtoschar(const char *s, char **endptr, int base) { 
    return (signed char) strto_subrange(s, endptr, base, SCHAR_MIN, SCHAR_MAX); 
} 

改善由@chqrlie

+0

您還應該包括'' – chqrlie 2016-03-08 19:55:55

+0

@chqrlie同意,編輯。 – chux 2016-03-08 20:05:12