最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語(yǔ)言實(shí)現(xiàn)將字符串轉(zhuǎn)換成整數(shù)

 更新時(shí)間:2023年04月06日 09:16:29   作者:努力學(xué)習(xí)游泳的魚(yú)  
這篇文章主要為大家詳細(xì)介紹了如何用C語(yǔ)言寫(xiě)一個(gè)函數(shù),把字符串轉(zhuǎn)換成整數(shù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

這是一個(gè)很有意思的問(wèn)題。請(qǐng)不要把這個(gè)問(wèn)題想的太簡(jiǎn)單了,考慮問(wèn)題時(shí)應(yīng)該盡可能的全面一些。請(qǐng)先思考并且實(shí)現(xiàn)這個(gè)函數(shù),再來(lái)看講解。

分析一下:函數(shù)名是StrToInt,那么可以這么調(diào)用:

int ret = StrToInt("1234");
printf("%d\n", ret);

如果你寫(xiě)的程序能夠正確輸出1234,然后就覺(jué)得這道題就這樣了,那么考慮的就不夠全面。有沒(méi)有一種可能:

1.傳參時(shí)傳了NULL指針。

2.傳入空字符串。

3.字符串前面有空格,如:" 1234"。

4.有正負(fù)號(hào),如:“-1234”。

5.有非法字符,如:“1234abcd”。

6.數(shù)字太大了,超出了int的存儲(chǔ)范圍,如:“1111111111111111111111111111111111111”。

下面我們一個(gè)一個(gè)解決。

準(zhǔn)備工作

由于有可能出現(xiàn)非法字符,或者空字符串等,會(huì)有一些情況的轉(zhuǎn)換是非法的。所以,定義一個(gè)全局性質(zhì)的枚舉類型來(lái)檢驗(yàn)轉(zhuǎn)換是否合法:

enum State
{
    VALID,
    INVALID
}s = INVALID;

默認(rèn)的情況是非法的,只有轉(zhuǎn)換成功才會(huì)把s的值置為VALID。

先把函數(shù)的框架撘出來(lái):

int StrToInt(const char* str)
{

???????}

接下來(lái)開(kāi)始解決以下問(wèn)題:

1.NULL指針

NULL指針是不能解引用的!所以最好斷言一下。

int StrToInt(const char* str)
{
	// 如果str是NULL,不能對(duì)其解引用
	assert(str);

	return ret;
}

2.空字符串

如果一上來(lái)就遇到了’\0’,那么就是空字符串。

int StrToInt(const char* str)
{
	// 如果str是NULL,不能對(duì)其解引用
	assert(str);

	// 空字符串
	if (*str == '\0')
	{
		return 0;
	}
}

3.空格

接下來(lái),有可能會(huì)遇到空格,使用isspace函數(shù)來(lái)判斷,把空格跳過(guò)去。

int StrToInt(const char* str)
{
	// 如果str是NULL,不能對(duì)其解引用
	assert(str);

	// 空字符串
	if (*str == '\0')
	{
		return 0;
	}
	// 空格
	while (isspace(*str))
	{
		++str;
	}
}

4.正負(fù)號(hào)

接下來(lái)有可能遇到正負(fù)號(hào),用一個(gè)flag來(lái)保存。

int StrToInt(const char* str)
{
	// 如果str是NULL,不能對(duì)其解引用
	assert(str);

	// 空字符串
	if (*str == '\0')
	{
		return 0;
	}
	// 空格
	while (isspace(*str))
	{
		++str;
	}
	// 正負(fù)號(hào)
	int flag = 1;
	if (*str == '+')
	{
		flag = 1;
		++str;
	}
	else if (*str == '-')
	{
		flag = -1;
		++str;
	}
}

5.非法字符

下面開(kāi)始處理數(shù)字。但是,有可能會(huì)遇到非法字符,所以要先判斷一下。

int StrToInt(const char* str)
{
	// 如果str是NULL,不能對(duì)其解引用
	assert(str);

	// 空字符串
	if (*str == '\0')
	{
		return 0;
	}
	// 空格
	while (isspace(*str))
	{
		++str;
	}
	// 正負(fù)號(hào)
	int flag = 1;
	if (*str == '+')
	{
		flag = 1;
		++str;
	}
	else if (*str == '-')
	{
		flag = -1;
		++str;
	}

	// 處理數(shù)字
	while (*str)
	{
		if (isdigit(*str))
		{

		}
		else
		{
			return ret;
		}
	}
}

如何處理合法的數(shù)字呢?假設(shè)是1234,我們可以先定義一個(gè)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 + 拿到的數(shù)字就行了。但是“拿到的數(shù)字”是什么呢?就是*str-'0'。想象一下,'1'-'0'就是數(shù)字1,'6'-'0'就是數(shù)字6。兩個(gè)字符相減就是對(duì)應(yīng)的ASCII碼相減。不過(guò),拿到的數(shù)字得乘上flag再加上去,因?yàn)橛锌赡苁秦?fù)數(shù)。

int StrToInt(const char* str)
{
	// 如果str是NULL,不能對(duì)其解引用
	assert(str);

	// 空字符串
	if (*str == '\0')
	{
		return 0;
	}
	// 空格
	while (isspace(*str))
	{
		++str;
	}
	// 正負(fù)號(hào)
	int flag = 1;
	if (*str == '+')
	{
		flag = 1;
		++str;
	}
	else if (*str == '-')
	{
		flag = -1;
		++str;
	}

	// 處理數(shù)字
	int ret = 0;
	while (*str)
	{
		if (isdigit(*str))
		{
			ret = ret * 10 + flag * (*str - '0');
			++str;
		}
		else
		{
			return ret;
		}
	}

	s = VALID;
	return (int)ret;
}

6.越界

這就完了嗎?還有一種情況,假設(shè)傳入的數(shù)字過(guò)大或過(guò)小,導(dǎo)致超出了int的存儲(chǔ)范圍,此時(shí)的轉(zhuǎn)換也是非法的。判斷方法,就是用更大的類型,如long long來(lái)存儲(chǔ),如果超出了int的存儲(chǔ)范圍(ret>INT_MAX || ret<INT_MIN),但是不會(huì)超出long long的存儲(chǔ)范圍,就能夠識(shí)別什么時(shí)候越界了。

int StrToInt(const char* str)
{
	// 如果str是NULL,不能對(duì)其解引用
	assert(str);

	// 空字符串
	if (*str == '\0')
	{
		return 0;
	}
	// 空格
	while (isspace(*str))
	{
		++str;
	}
	// 正負(fù)號(hào)
	int flag = 1;
	if (*str == '+')
	{
		flag = 1;
		++str;
	}
	else if (*str == '-')
	{
		flag = -1;
		++str;
	}

	// 處理數(shù)字
	long long ret = 0;
	while (*str)
	{
		if (isdigit(*str))
		{
			ret = ret * 10 + flag * (*str - '0');
			// 判斷有沒(méi)有超過(guò)int的存儲(chǔ)范圍
			if (ret > INT_MAX || ret < INT_MIN)
			{
				return (int)ret;
			}
			else
			{
				++str;
			}
		}
		else
		{
			return (int)ret;
		}
	} // end of while

	s = VALID;
	return (int)ret;
}

最后如果轉(zhuǎn)換成功,就把s置成VALID,再返回ret即可。注意ret是long long類型,但是返回類型是int,所以需要強(qiáng)制類型轉(zhuǎn)換。

測(cè)試

完整的測(cè)試代碼如下:

#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,不能對(duì)其解引用
	assert(str);

	// 空字符串
	if (*str == '\0')
	{
		return 0;
	}
	// 空格
	while (isspace(*str))
	{
		++str;
	}
	// 正負(fù)號(hào)
	int flag = 1;
	if (*str == '+')
	{
		flag = 1;
		++str;
	}
	else if (*str == '-')
	{
		flag = -1;
		++str;
	}

	// 處理數(shù)字
	long long ret = 0;
	while (*str)
	{
		if (isdigit(*str))
		{
			ret = ret * 10 + flag * (*str - '0');
			// 判斷有沒(méi)有超過(guò)int的存儲(chǔ)范圍
			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("轉(zhuǎn)換成功:%d\n", ret);
	}
	else
	{
		printf("轉(zhuǎn)換失?。?d\n", ret);
	}

	return 0;
}

輸出結(jié)果:

總結(jié)

1.每次把舊的數(shù)乘10再加上一個(gè)數(shù)字,就能在這個(gè)數(shù)后面續(xù)上這個(gè)數(shù)字。如123*10+4=1234,就在123后面續(xù)上了4。

2.字符相減,本質(zhì)是ASCII碼相減。

3.考慮問(wèn)題時(shí),應(yīng)該全面考慮,不要漏掉一些情況。

到此這篇關(guān)于C語(yǔ)言實(shí)現(xiàn)將字符串轉(zhuǎn)換成整數(shù)的文章就介紹到這了,更多相關(guān)C語(yǔ)言字符串轉(zhuǎn)整數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

会泽县| 沙坪坝区| 阿图什市| 雷山县| 仙游县| 广灵县| 新津县| 肇州县| 兖州市| 三门峡市| 三穗县| 谢通门县| 花莲县| 察哈| 都匀市| 洪湖市| 芜湖县| 芜湖市| 桃园市| 乐昌市| 卓资县| 隆德县| 拜城县| 阳春市| 长岭县| 秦安县| 边坝县| 黄石市| 锡林郭勒盟| 永吉县| 永善县| 德庆县| 瓦房店市| 静宁县| 上饶县| 共和县| 耒阳市| 佛山市| 九龙城区| 广州市| 米脂县|