C語(yǔ)言中atoi函數(shù)模擬實(shí)現(xiàn)詳析
一、atoi函數(shù)是什么?
int atoi ( const char * str );
功能:將字符串轉(zhuǎn)換為整數(shù)。
解析C字符串str,將其內(nèi)容解釋為一個(gè)整數(shù),該整數(shù)作為int值返回。
該函數(shù)首先丟棄盡可能多的空白字符,直到找到第一個(gè)非空白字符。然后,從這個(gè)字符開(kāi)始,取一個(gè)可選的初始加號(hào)或減號(hào),后面跟著盡可能多的數(shù)字,并將它們解釋為一個(gè)數(shù)值。 例:" -123456" 轉(zhuǎn)換為 -123456
字符串可以在構(gòu)成整數(shù)的字符之后包含其他字符,這些字符將被忽略,并且對(duì)該函數(shù)的行為沒(méi)有影響。例:" 123abc456" 轉(zhuǎn)換為 123,雖然最終的輸出結(jié)果是一個(gè)整數(shù),但這屬于非法轉(zhuǎn)換
如果str中的第一個(gè)非空白字符序列不是有效的整數(shù),或者由于str為空或只包含空白字符而不存在這樣的序列,則不執(zhí)行轉(zhuǎn)換。例:“abc” " abc" “” 為非法轉(zhuǎn)換,最終會(huì)輸出整數(shù)0。
字符串 | 整數(shù) | 合法性 |
---|---|---|
" 123456" | 123456 | 合法 |
“-123456” | -123456 | 合法 |
“123abc456” | 123 | 非法 |
“abc” | 0 | 非法 |
“” | 0 | 非法 |
“2222222222” | 任意值 | 非法 |
注:當(dāng)轉(zhuǎn)換的值超出int可表示值的范圍時(shí)會(huì)發(fā)生什么,沒(méi)有標(biāo)準(zhǔn)規(guī)范。
例:在VS2013編譯環(huán)境下輸出的數(shù)值
二、atoi函數(shù)模擬實(shí)現(xiàn)
#include <stdio.h> #include <limits.h> #include <ctype.h> //通過(guò)枚舉設(shè)置兩種狀態(tài),分別代表字符串轉(zhuǎn)換的合法性 enum Status { VALID, //合法 INVALID //非法 }; enum Status status = INVALID; //定義全局變量 status 為 INVALID,若轉(zhuǎn)換合法,則將 status 變?yōu)?VALID,若非法則不變 int my_atoi(const char* str) { if (str == NULL) //字符串為空 { return 0; } if (*str == '\0') //空白字符 { return 0; } while (isspace(*str)) //字符串前面有多余的空格,則一直往后移尋找符號(hào)或數(shù)字 { str++; } int flag = 0; //flag 標(biāo)志數(shù)字的正負(fù) if (*str == '+') { flag = 1; str++; } else if (*str == '-') { flag = -1; str++; } long long ret = 0; while (isdigit(*str)) { ret = ret * 10 + flag*(*str - '0'); if (ret<INT_MIN || ret>INT_MAX) //判斷轉(zhuǎn)換后的數(shù)字是否越界 { return 0; } str++; } if (*str == '\0') //若字符串遍歷完就走這一步,也就意味著該字符串的轉(zhuǎn)換為合法的 { status = VALID; return (int)ret; } else //非法轉(zhuǎn)換 { return (int)ret; } } int main() { //int ret = my_atoi("-123"); int ret = my_atoi(" -2222222222"); if (status == VALID) { printf("合法的轉(zhuǎn)換:%d\n", ret); } else printf("轉(zhuǎn)換不合法!返回值為:%d\n",ret); return 0; }
總結(jié)
基本上該函數(shù)的模擬實(shí)現(xiàn)要注意的細(xì)節(jié)都在上面的代碼注釋里。
還要再解釋的是為什么要將返回值定義成 long long 長(zhǎng)整型,而不是stoi函數(shù)的返回值 int 型呢?
這是因?yàn)樵谟?jì)算求和的時(shí)候萬(wàn)一出現(xiàn)越界,由于之前將返回值定義為 int 型,這時(shí)就會(huì)將已經(jīng)越界的數(shù)字強(qiáng)制轉(zhuǎn)換為非越界的數(shù)字,那么就會(huì)導(dǎo)致錯(cuò)誤的輸出結(jié)果和錯(cuò)誤的合法性判斷。
到此這篇關(guān)于C語(yǔ)言中atoi函數(shù)模擬實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)C語(yǔ)言atoi函數(shù)模擬內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++自動(dòng)析構(gòu)時(shí)的順序問(wèn)題
這篇文章主要介紹了C++自動(dòng)析構(gòu)時(shí)的順序,通過(guò)實(shí)例代碼給大家講解了C++ 構(gòu)造與析構(gòu)的執(zhí)行順序,代碼簡(jiǎn)單易懂,非常不錯(cuò)對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-03-03使用Qt/C++實(shí)現(xiàn)WGS84,高德GCJ-02與百度BD-09坐標(biāo)系間相互轉(zhuǎn)化
這篇文章主要為大家詳細(xì)介紹了如何使用Qt實(shí)現(xiàn)WGS84、高德GCJ-02與百度BD-09坐標(biāo)系間相互轉(zhuǎn)化,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-07-07C語(yǔ)言變量類(lèi)型與輸出控制用法實(shí)例教程
這篇文章主要介紹了C語(yǔ)言變量類(lèi)型與輸出控制用法,是C語(yǔ)言程序設(shè)計(jì)中比較基礎(chǔ)也是比較重要的用法,需要的朋友可以參考下2014-08-08怎么實(shí)現(xiàn)類(lèi)的成員函數(shù)作為回調(diào)函數(shù)
不使用成員函數(shù),為了訪問(wèn)類(lèi)的成員變量,可以使用友元操作符(friend),在C++中將該函數(shù)說(shuō)明為類(lèi)的友元即可2013-10-10C++之IO類(lèi),文件輸入輸出,string流練習(xí)題
這篇文章主要介紹了C++實(shí)現(xiàn)IO類(lèi)的幾道數(shù)組練習(xí)題,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-09-09