atoi()函數解析以及缺陷分析,以及對atoi()、atof()的改造

1、atoi()解析

atoi()原型:  int atoi(const char *str );

函數功能:把字符串轉換成整型數。

參數str:要進行轉換的字符串

返回值:每個函數返回 int 值,此值由將輸入字符作爲數字解析而生成。 如果該輸入無法轉換爲該類型的值,則atoi的返回值爲 0。

注意:使用該函數時要注意atoi返回的是int類型,注意輸入str的範圍不要超出int類型的範圍。

#include <stdio.h>
#include <stdlib.h>

int main()
{
	int a;

	char *ptr1 = "3124";
	char *ptr2 = "0";
	char *ptr3 = "12.33";
	char *ptr4 = "-1245";
	char *ptr5 = "+21";
	char *ptr6 = "s3241";

	a = atoi(ptr1);
	printf("\"%s\"\t-> %d\n",ptr1, a);

	a = atoi(ptr2);
	printf("\"%s\"\t-> %d\n",ptr2, a);

	a = atoi(ptr3);
	printf("\"%s\"\t-> %d\n",ptr3, a);

	a = atoi(ptr4);
	printf("\"%s\"\t-> %d\n",ptr4, a);

	a = atoi(ptr5);
	printf("\"%s\"\t-> %d\n",ptr5, a);

	a = atoi(ptr6);
	printf("\"%s\"\t-> %d\n",ptr6, a);

	return 0;
}

打印如下:

"3124"     -> 3124
"0"           -> 0
"12.33"    -> 12
"-1245"    -> -1245
"+21"       -> 21
"s3241"    -> 0


2、atoi()函數缺陷分析

 從上述打印能夠看出來,要是首字母是非法字母,及無法轉換的類型,是輸出爲0的。這可能會造成災難性的結果,因爲不知道是輸入0字符串還是非法字符串。

比如工控上鑽頭移動座標(x,y,z)。x,y,z三個座標是靠服務器下發下來,若程序錯誤,傳入了一個錯誤的結果(s12,3,4)(已字符串形式下發),如果直接調用atoi,必然解析成(0,3,4),移動到了錯誤的位置!

當然可以對輸入的字符串進行檢查,可爲啥不在atoi裏面檢查呢?

 

3、aioi()函數改造


/*
用法:將字符串裏的數字字符轉化爲整形數。並返回處理的字符個數。

注意:轉化時跳過前面的空格等空字符,直到遇上數字或正負符號纔開始做轉換,
而再遇到非數字或字符串結束標誌('/0')才結束轉換,並將結果返回。
目的是改造atoi函數

處理失敗或者沒有整型字符串則返回0,處理成功發回處理字符串的個數

*/
int CM_Atoi(char* source,int* integer)
{
	int offset1,offset2,num;
	int signedflag;//+爲1 -爲0

	if(source == NULL || integer == NULL)
	{
		return 0;
	}

	offset1 = 0;
	offset2 = 0;
	num = 0;

	while(*source <= 32)//去除首部空格 \r \n \t \r 等異常字符
	{
		source++;
		offset1++;
	}

	signedflag = 1;//默認爲+
	if(*source == '+')
	{
		signedflag = 1;
		source++;
		offset1++;
	}
	else if(*source == '-')
	{
		signedflag = 0;
		source++;
		offset1++;
	}

	while(*source != '\0' && *source >= '0' && *source <= '9')
	{
		num = *source- '0' + num*10;
		source++;
		offset2++;
	}

	if(signedflag == 0)
	{
		num = -num;
	}

	if(offset2)
	{
		*integer = num;
		return offset1+offset2;
	}
	else
	{
		return 0;
	}
}

轉發的整型已指針帶入,返回轉換的成功的字符串個數,應用層對CM_Atoi()函數返回值做檢查,若返回爲0,則比如轉換失敗,大於0,才成功轉換成功。

 

4、atof()函數改造

同樣方法對atof進行改造

/*
簡單的x的y次冪
*/
long long pow1(int x,int y)
{
	long long num = 1;
	int i;

	for(i = 0; i < y; i++)
	{
		num = num*x;
	}

	return num;
}

/*
用法:將字符串裏的數字字符轉化爲浮點型。並返回處理的字符個數。

注意:轉化時跳過前面的空格等空字符,直到遇上數字或正負符號纔開始做轉換,
而再遇到非數字或字符串結束時('/0')才結束轉換,並將結果返回。
目的是改造atof函數
處理失敗或者沒有浮點型字符串則返回0
支持正負號
*/

int CM_Atof(char* source,double* doubleing)
{
	int offset1,offset2,n;
	double num;
	int signedflag;//+爲1 -爲0

	if(source == NULL || doubleing == NULL)
	{
		return 0;
	}

	offset1 = 0;
	offset2 = 0;
	num = 0.0;

	while(*source <= 32)//去除首部空格 \r \n \t \r 等異常字符
	{
		source++;
		offset1++;
	}

	signedflag = 1;//默認爲+
	if(*source == '+')
	{
		signedflag = 1;
		source++;
		offset1++;
	}
	else if(*source == '-')
	{
		signedflag = 0;
		source++;
		offset1++;
	}


	//整數部分
	while(*source != '\0' && *source >= '0' && *source <= '9')
	{
		num = *source- '0' + num*10.0;
		source++;
		offset2++;
	}

	if(offset2 != 0 && *source == '.')
	{
		source++;
		offset2++;

		//小數部分
		n = 0;
		while(*source != '\0' && *source >= '0' && *source <= '9')
		{
			num = (*source- '0')*(1.0/pow1(10,++n)) + num;
			source++;
			offset2++;
		}
	}

	if(signedflag == 0)
	{
		num = -num;
	}

	if(offset2)
	{
		*doubleing = num;
		return offset1+offset2;
	}
	else
	{
		return 0;
	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章