C语言中字符串与数字互相转换的函数
acmilan2017/02/26软件综合 IP:四川

字符串转换成数字

首先,不建议使用sscanf和atoi、atol、atoll、atof,它们无法检测溢出,而且atoX系列无法得知转换在何时结束。

C89函数,字节字符串:

  • strtol - 32位(windows)/64位(linux)有符号整数long,可指定进制
  • strtoul - 32位(windows)/64位(linux)无符号整数unsigned long,可指定进制
  • strtod - 双精度浮点数double

C95函数,宽字符串:

  • wcstol - 32位(windows)/64位(linux)有符号整数long,可指定进制
  • wcstoul - 32位(windows)/64位(linux)无符号整数unsigned long,可指定进制
  • wcstod - 双精度浮点数double

C99函数,字节字符串(需要VC2013):

  • strtoll - 64位有符号整数long long,可指定进制
  • strtoull - 64位无符号整数unsigned long long,可指定进制
  • strtoimax - 64位有符号整数intmax_t,可指定进制
  • strtoumax - 64位无符号整数uintmax_t,可指定进制
  • strtof - 单精度浮点数float
  • strtold - 扩展双精度浮点数long double

C99函数,宽字符串(需要VC2013):

  • wcstoll - 64位有符号整数long long,可指定进制
  • wcstoull - 64位无符号整数unsigned long long,可指定进制
  • wcstoimax - 64位有符号整数intmax_t,可指定进制
  • wcstoumax - 64位无符号整数uintmax_t,可指定进制
  • wcstof - 单精度浮点数float
  • wcstold - 扩展双精度浮点数long double

MSVC函数,字节字符串:

  • _strtoi64 - 64位(windows)有符号整数__int64,可指定进制
  • _strtoui64 - 64位(windows)无符号整数unsigned __int64,可指定进制

MSVC函数,宽字符串:

  • _wcstoi64 - 64位(windows)有符号整数__int64,可指定进制
  • _wcstoui64 - 64位(windows)无符号整数unsigned __int64,可指定进制
<code class="language-cpp">// long long and unsigned long long
#define strtoll _strtoi64
#define strtoull _strtoui64
#define wcstoll _wcstoi64
#define wcstoull _wcstoui64
// intmax_t and uintmax_t
#define strtoimax _strtoi64
#define strtoumax _strtoui64
#define wcstoimax _wcstoi64
#define wcstoumax _wcstoui64
// float
static float strtof(char *pstr, char **ppend) {
	double dblval = strtod(pstr, ppend);
	if ((_finite(dblval) && !_finite((float)dblval)) ||
		(dblval != 0 && (float)dblval == 0)) {
			errno = ERANGE;
	}
	return (float)dblval;
}
static float wcstof(wchar_t *pstr, wchar_t **ppend) {
	double dblval = wcstod(pstr, ppend);
	if ((_finite(dblval) && !_finite((float)dblval)) ||
		(dblval != 0 && (float)dblval == 0)) {
			errno = ERANGE;
	}
	return (float)dblval;
}
// long double
static long double strtold(char *pstr, char **ppend) { double dblval = strtod(pstr, ppend); return dblval; }
static long double wcstold(wchar_t *pstr, wchar_t **ppend) { double dblval = wcstod(pstr, ppend); return dblval; }
</code>

数字转换成字符串

数字转换成字符串,一般使用sprintf系列。由于一些历史的原因,sprintf系列函数发生了比较复杂的演化。

不安全版本函数的支持情况:

  • 原生支持C89标准的sprintf
  • 原生支持C89标准的vsprintf
  • 原生支持非标准的swprintf,VC2005后改为_swprintf
  • 原生支持非标准的vswprintf,VC2005后改为_vswprintf

安全版本函数的支持情况:

  • 原生支持非标准的_snprintf,见注释
  • 原生支持非标准的_snwprintf,见注释
  • 原生支持非标准的_vsnprintf,见注释(VC2015之前还被定义为vsnprintf)
  • 原生支持非标准的_vsnwprintf,见注释
  • VC2005开始支持C95标准的swprintf(替换之前的不安全版本)
  • VC2005开始支持C95标准的vswprintf(替换之前的不安全版本)
  • VC2015开始支持C99标准的snprintf
  • VC2015开始支持C99标准的vsnprintf(替换之前的非标准版本)

如果不需要安全性,可以直接使用sprintf和_swprintf。

如果需要兼容老版本VC,需要使用_snprintf和_snwprintf。

如果只需要兼容VC2005+,可以使用_snprintf和swprintf。

如果只需要兼容VC2015+,可以使用snprintf和swprintf。

注意_snprintf和_snwprintf和标准的版本不同:

_snprintf和_snwprintf字符串不溢出时会用一个0截断,字符串溢出时不会截断。

VC2015:

<code class="language-cpp">char buf[bufsz];
snprintf(buf, bufsz, "fmt", ...);
</code>

老版本VC实现方法:

<code class="language-cpp">char buf[bufsz];
memset(buf, 0, bufsz);
_snprintf(buf, bufsz - 1, "fmt", ...);
</code>

如果需要动态分配内存:

<code class="language-cpp">#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()
{
	char *buf = NULL;
	int reqsz = 0;

	reqsz = _snprintf(NULL, 0, "%d", 12);
	buf = malloc(reqsz + 1);
	memset(buf, 0, reqsz + 1);
	_snprintf(buf, reqsz, "%d", 12);

	printf("%s\n", buf);

	free(buf);
	return 0;
}
</stdlib.h></string.h></stdio.h></code>

[修改于 7年2个月前 - 2017/03/03 18:48:20]

来自:计算机科学 / 软件综合
1
已屏蔽 原因:{{ notice.reason }}已屏蔽
{{notice.noticeContent}}
~~空空如也

想参与大家的讨论?现在就 登录 或者 注册

所属专业
上级专业
同级专业
acmilan
进士 学者 笔友
文章
461
回复
2934
学术分
4
2009/05/30注册,5年3个月前活动
暂无简介
主体类型:个人
所属领域:无
认证方式:邮箱
IP归属地:未同步
文件下载
加载中...
{{errorInfo}}
{{downloadWarning}}
你在 {{downloadTime}} 下载过当前文件。
文件名称:{{resource.defaultFile.name}}
下载次数:{{resource.hits}}
上传用户:{{uploader.username}}
所需积分:{{costScores}},{{holdScores}}下载当前附件免费{{description}}
积分不足,去充值
文件已丢失

当前账号的附件下载数量限制如下:
时段 个数
{{f.startingTime}}点 - {{f.endTime}}点 {{f.fileCount}}
视频暂不能访问,请登录试试
仅供内部学术交流或培训使用,请先保存到本地。本内容不代表科创观点,未经原作者同意,请勿转载。
音频暂不能访问,请登录试试
支持的图片格式:jpg, jpeg, png
插入公式
评论控制
加载中...
文号:{{pid}}
投诉或举报
加载中...
{{tip}}
请选择违规类型:
{{reason.type}}

空空如也

加载中...
详情
详情
推送到专栏从专栏移除
设为匿名取消匿名
查看作者
回复
只看作者
加入收藏取消收藏
收藏
取消收藏
折叠回复
置顶取消置顶
评学术分
鼓励
设为精选取消精选
管理提醒
编辑
通过审核
评论控制
退修或删除
历史版本
违规记录
投诉或举报
加入黑名单移除黑名单
查看IP
{{format('YYYY/MM/DD HH:mm:ss', toc)}}