用C语言写一个函数,把字符串转换成整数

这篇具有很好参考价值的文章主要介绍了用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)
{

}

接下来开始解决以下问题:

1.NULL指针

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

int StrToInt(const char* str)
{
	// 如果str是NULL,不能对其解引用
	assert(str != NULL);

	return ret;
}

2.空字符串

如果一上来就遇到了’\0’,那么就是空字符串。

int StrToInt(const char* str)
{
	// 如果str是NULL,不能对其解引用
	assert(str != NULL);

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

3.空格

接下来,有可能会遇到空格,使用isspace函数来判断,把空格跳过去。

int StrToInt(const char* str)
{
	// 如果str是NULL,不能对其解引用
	assert(str != NULL);

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

4.正负号

接下来有可能遇到正负号,用一个flag来保存。

int StrToInt(const char* str)
{
	// 如果str是NULL,不能对其解引用
	assert(str != NULL);

	// 空字符串
	if (*str == '\0')
	{
		return 0;
	}
	// 空格
	while (isspace(*str))
	{
		++str;
	}
	// 正负号
	int flag = 1;
	if (*str == '+')
	{
		flag = 1;
		++str;
	}
	else if (*str == '-')
	{
		flag = -1;
		++str;
	}
}

5.非法字符

下面开始处理数字。但是,有可能会遇到非法字符,所以要先判断一下。

int StrToInt(const char* str)
{
	// 如果str是NULL,不能对其解引用
	assert(str != NULL);

	// 空字符串
	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 != '\0')
	{
		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 != NULL);

	// 空字符串
	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 != '\0')
	{
		if (isdigit(*str))
		{
			ret = ret * 10 + flag * (*str - '0');
			++str;
		}
		else
		{
			return ret;
		}
	}

	s = VALID;
	return ret;
}

6.越界

这就完了吗?还有一种情况,假设传入的数字过大或过小,导致超出了int的存储范围,此时的转换也是非法的。判断方法,就是用更大的类型,如long long来存储,如果超出了int的存储范围(ret>INT_MAX || ret<INT_MIN),但是不会超出long long的存储范围,就能够识别什么时候越界了。

int StrToInt(const char* str)
{
	// 如果str是NULL,不能对其解引用
	assert(str != NULL);

	// 空字符串
	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 != '\0')
	{
		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 != NULL);

	// 空字符串
	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 != '\0')
	{
		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语言写一个函数,把字符串转换成整数

总结

  1. 每次把旧的数乘10再加上一个数字,就能在这个数后面续上这个数字。如123*10+4=1234,就在123后面续上了4。
  2. 字符相减,本质是ASCII码相减。
  3. 考虑问题时,应该全面考虑,不要漏掉一些情况。

感谢大家的阅读!文章来源地址https://www.toymoban.com/news/detail-408664.html

到了这里,关于用C语言写一个函数,把字符串转换成整数的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • LeetCode-字符串转换整数atoi(8)

    LeetCode-字符串转换整数atoi(8)

    请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数)。 函数 myAtoi(string s) 的算法如下: 读入字符串并丢弃无用的前导空格 检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果

    2024年01月16日
    浏览(8)
  • Leetcode 8. 字符串转换整数 (atoi)

    请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数)。 函数 myAtoi(string s) 的算法如下: 读入字符串并丢弃无用的前导空格 检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果

    2024年04月09日
    浏览(10)
  • C语言:写一个函数,求字符串的长度,在main函数中输入字符串并输出其长度(指针)

    C语言:写一个函数,求字符串的长度,在main函数中输入字符串并输出其长度(指针)

    分析:    在程序中,定义一个函数 fix,该函数使用指针变量来访问字符串中的每个字符,并计算出字符串的长度。fix 函数的参数为指向 char 类型的指针变量 p,表示需要计算长度的字符串。   在主函数 main 中,定义一个大小为 20 的字符数组 a,用于存储输入的字符串。然

    2024年01月21日
    浏览(35)
  • 【C语言_题库】C语言:编写一个程序,输入一组字符串,将字符串中的小写字母转换为大写字母,其它字符不变,并输出。

    【C语言_题库】C语言:编写一个程序,输入一组字符串,将字符串中的小写字母转换为大写字母,其它字符不变,并输出。

    【问题描述】 从键盘输入一行英文字符串,把所有小写字母变成大写字母,其他字母和字符保持不变。 【输入形式】 输入一行字符串,含大小写。 【输出形式】 输出大写字母形式。 【样例输入①】 hello,world. 【样例输出①】 result:HELLO,WORLD. 【样例输入②】 hello,China. 【样例

    2024年02月07日
    浏览(197)
  • 【LeetCode】字符串转换整数 (atoi) [M](模拟)

    8. 字符串转换整数 (atoi) - 力扣(LeetCode) 请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数)。 函数 myAtoi(string s) 的算法如下: 读入字符串并丢弃无用的前导空格 检查下一个字符(假设还未到字符末尾)为正还是负

    2024年02月07日
    浏览(11)
  • 【LeetCode-中等】剑指 Offer 67. 把字符串转换成整数(详解)

    【LeetCode-中等】剑指 Offer 67. 把字符串转换成整数(详解)

    写一个函数 StrToInt,实现把字符串转换成整数这个功能。不能使用 atoi 或者其他类似的库函数。 首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。 当我们寻找到的第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续

    2024年02月15日
    浏览(11)
  • C++中如何将string(字符串)转换为int(整数)

    C++ 编程语言有一些内置数据类型: int , 对于整数(例如 10、150) double ,对于浮点数(例如 5.0、4.5) char ,对于单个字符(例如“D”、“!”) string ,对于字符序列(例如“Hello”) bool , 对于布尔值(true 或 false) C++ 是一种 强类型 编程语言,这意味着当您创建变量时,你

    2024年02月06日
    浏览(63)
  • 汇编语言(Assembly Language)习题:键盘输入一个字符串,试将其中的小写字母转换为大写字母,其它字符保持不变。

    汇编语言(Assembly Language)习题:键盘输入一个字符串,试将其中的小写字母转换为大写字母,其它字符保持不变。

    前置知识:汇编语言常用系统功能调用(如果懂直接跳过看题目详解) 格式: 功能:从键盘输入字符的ASCII码送入寄存器AL中,并送显示器显示。 格式: 功能:将DL寄存器中的字符送显示器显示,如果DL中为〈CTRL〉+〈BREAK〉的ASCII码,则退出。 格式: 功能:将DL寄存器中的字

    2024年02月03日
    浏览(35)
  • (其他) 剑指 Offer 67. 把字符串转换成整数 ——【Leetcode每日一题】

    (其他) 剑指 Offer 67. 把字符串转换成整数 ——【Leetcode每日一题】

    难度:中等 写一个函数 StrToInt,实现把字符串转换成整数这个功能。不能使用 atoi 或者其他类似的库函数。 首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。 当我们寻找到的第一个非空字符为正或者负号时,则将该符号与之后面尽可

    2024年02月09日
    浏览(8)
  • Java——它要求用户输入一个整数(实际上是一个字符串),然后计算该整数的平方值,并将结果输出。

    Java——它要求用户输入一个整数(实际上是一个字符串),然后计算该整数的平方值,并将结果输出。

    这是一个Java程序,它要求用户输入一个整数(实际上是一个字符串),然后计算该整数的平方值,并将结果输出。程序的基本流程如下: 首先,声明并初始化变量data和result,它们的初始值都为0。 然后,输出提示信息,要求用户输入一个整数。 接下来,使用BufferedReader类从

    2024年02月11日
    浏览(7)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包