您好,登錄后才能下訂單哦!
本文小編為大家詳細介紹“C語言如何實現將字符串轉換成整數”,內容詳細,步驟清晰,細節處理妥當,希望這篇“C語言如何實現將字符串轉換成整數”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。
這是一個很有意思的問題。請不要把這個問題想的太簡單了,考慮問題時應該盡可能的全面一些。請先思考并且實現這個函數,再來看講解。
分析一下:函數名是StrToInt,那么可以這么調用:
int ret = StrToInt("1234"); printf("%d\n", ret);
如果你寫的程序能夠正確輸出1234,然后就覺得這道題就這樣了,那么考慮的就不夠全面。有沒有一種可能:
1.傳參時傳了NULL指針。
2.傳入空字符串。
3.字符串前面有空格,如:" 1234"。
4.有正負號,如:“-1234”。
5.有非法字符,如:“1234abcd”。
6.數字太大了,超出了int的存儲范圍,如:“1111111111111111111111111111111111111”。
下面我們一個一個解決。
由于有可能出現非法字符,或者空字符串等,會有一些情況的轉換是非法的。所以,定義一個全局性質的枚舉類型來檢驗轉換是否合法:
enum State { VALID, INVALID }s = INVALID;
默認的情況是非法的,只有轉換成功才會把s的值置為VALID。
先把函數的框架撘出來:
int StrToInt(const char* str) { }
接下來開始解決以下問題:
NULL指針是不能解引用的!所以最好斷言一下。
int StrToInt(const char* str) { // 如果str是NULL,不能對其解引用 assert(str); return ret; }
如果一上來就遇到了’\0’,那么就是空字符串。
int StrToInt(const char* str) { // 如果str是NULL,不能對其解引用 assert(str); // 空字符串 if (*str == '\0') { return 0; } }
接下來,有可能會遇到空格,使用isspace函數來判斷,把空格跳過去。
int StrToInt(const char* str) { // 如果str是NULL,不能對其解引用 assert(str); // 空字符串 if (*str == '\0') { return 0; } // 空格 while (isspace(*str)) { ++str; } }
接下來有可能遇到正負號,用一個flag來保存。
int StrToInt(const char* str) { // 如果str是NULL,不能對其解引用 assert(str); // 空字符串 if (*str == '\0') { return 0; } // 空格 while (isspace(*str)) { ++str; } // 正負號 int flag = 1; if (*str == '+') { flag = 1; ++str; } else if (*str == '-') { flag = -1; ++str; } }
下面開始處理數字。但是,有可能會遇到非法字符,所以要先判斷一下。
int StrToInt(const char* str) { // 如果str是NULL,不能對其解引用 assert(str); // 空字符串 if (*str == '\0') { return 0; } // 空格 while (isspace(*str)) { ++str; } // 正負號 int flag = 1; if (*str == '+') { flag = 1; ++str; } else if (*str == '-') { flag = -1; ++str; } // 處理數字 while (*str) { if (isdigit(*str)) { } else { return ret; } } }
如何處理合法的數字呢?假設是1234,我們可以先定義一個ret,初始化成0。先拿到1,0*10+1,就得到了1。接著拿到2,1*10+2,就得到了12。再拿到3,12*10+3,就得到了123。最后拿到4,123*10+4,就得到了1234。以此類推。
每次ret = ret*10 + 拿到的數字就行了。但是“拿到的數字”是什么呢?就是*str-'0'。想象一下,'1'-'0'就是數字1,'6'-'0'就是數字6。兩個字符相減就是對應的ASCII碼相減。不過,拿到的數字得乘上flag再加上去,因為有可能是負數。
int StrToInt(const char* str) { // 如果str是NULL,不能對其解引用 assert(str); // 空字符串 if (*str == '\0') { return 0; } // 空格 while (isspace(*str)) { ++str; } // 正負號 int flag = 1; if (*str == '+') { flag = 1; ++str; } else if (*str == '-') { flag = -1; ++str; } // 處理數字 int ret = 0; while (*str) { if (isdigit(*str)) { ret = ret * 10 + flag * (*str - '0'); ++str; } else { return ret; } } s = VALID; return (int)ret; }
這就完了嗎?還有一種情況,假設傳入的數字過大或過小,導致超出了int的存儲范圍,此時的轉換也是非法的。判斷方法,就是用更大的類型,如long long來存儲,如果超出了int的存儲范圍(ret>INT_MAX || ret<INT_MIN),但是不會超出long long的存儲范圍,就能夠識別什么時候越界了。
int StrToInt(const char* str) { // 如果str是NULL,不能對其解引用 assert(str); // 空字符串 if (*str == '\0') { return 0; } // 空格 while (isspace(*str)) { ++str; } // 正負號 int flag = 1; if (*str == '+') { flag = 1; ++str; } else if (*str == '-') { flag = -1; ++str; } // 處理數字 long long ret = 0; while (*str) { if (isdigit(*str)) { ret = ret * 10 + flag * (*str - '0'); // 判斷有沒有超過int的存儲范圍 if (ret > INT_MAX || ret < INT_MIN) { return (int)ret; } else { ++str; } } else { return (int)ret; } } // end of while s = VALID; return (int)ret; }
最后如果轉換成功,就把s置成VALID,再返回ret即可。注意ret是long long類型,但是返回類型是int,所以需要強制類型轉換。
完整的測試代碼如下:
#include <stdio.h> #include <assert.h> #include <ctype.h> #include <limits.h> enum State { VALID, INVALID }s = INVALID; int StrToInt(const char* str) { // 如果str是NULL,不能對其解引用 assert(str); // 空字符串 if (*str == '\0') { return 0; } // 空格 while (isspace(*str)) { ++str; } // 正負號 int flag = 1; if (*str == '+') { flag = 1; ++str; } else if (*str == '-') { flag = -1; ++str; } // 處理數字 long long ret = 0; while (*str) { if (isdigit(*str)) { ret = ret * 10 + flag * (*str - '0'); // 判斷有沒有超過int的存儲范圍 if (ret > INT_MAX || ret < INT_MIN) { return (int)ret; } else { ++str; } } else { return (int)ret; } } // end of while s = VALID; return (int)ret; } int main() { int ret = StrToInt(" -1234"); if (s == VALID) { printf("轉換成功:%d\n", ret); } else { printf("轉換失敗:%d\n", ret); } return 0; }
輸出結果:
讀到這里,這篇“C語言如何實現將字符串轉換成整數”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。