C语言学习笔记 —— 转换函数
Posted Leung_ManWah
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言学习笔记 —— 转换函数相关的知识,希望对你有一定的参考价值。
一、字符串与数值互转
1.1 字符串转数值
1.1.1 字符串转整型
atoi
头文件:#include<stdlib.h>
功能 | 把字符串转换成整型数(忽略掉字符串左空格,直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束时(‘\\0’)才结束转换) |
---|---|
函数定义 | int atoi(const char *nptr) |
参数 | nptr:指向要转换的字符串 |
返回 | 返回转换后的整数值 |
用法:
#include <stdlib.h>
#include <stdio.h>
int main(void)
int n;
char *str = "12345.67";
n = atoi(str);
printf("n=%d\\n",n);
return 0;
输出:n = 12345
1.1.2 字符串转长整型
atol
头文件:#include<stdlib.h>
功能 | 把字符串转换成长整型数(忽略掉字符串左空格,直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束时(‘\\0’)才结束转换) |
---|---|
函数定义 | long atol(const char *nptr) |
参数 | nptr:指向要转换的字符串() |
返回 | 返回转换后的长整数值 |
用法:
#include <stdlib.h>
#include <stdio.h>
int main(void)
long l;
char *str = "98765432";
l = atol(str); /* 原来为l = atol(str); */
printf("l = %ld\\n", l);
return(0);
输出:l = 98765432
strtol
头文件:#include<stdlib.h>
功能 | 把字符串字符串根据参数base来转换成长整型数 |
---|---|
函数定义 | long int strtol(const char *nptr,char **endptr,int base) |
参数 | nptr:指向要转换的字符串 endptr:指向停止转换的位置,若字符串nptr的所有字符都成功转换成数字则endptr指向串结束符’\\0’ base:采用的进制方式,如base值为10则采用10进制,若base值为16则采用16进制等。当base值为0时则是采用10进制做转换,但遇到如’0x’前置字符则会使用16进制做转换、遇到’0’前置字符而不是’0x’的时候会使用8进制做转换 |
返回 | 返回转换后的长整型数,否则返回ERANGE并将错误代码存入errno中 |
特点:
-
不仅可以识别十进制整数,还可以识别其它进制的整数,取决于base参数,比如
strtol("0XDEADbeE~~", NULL, 16)
返回0xdeadbee的值,
strtol("0777~~", NULL, 8)
返回0777的值。 -
endptr是一个传出参数,函数返回时指向后面未被识别的第一个字符。
例如char *pos; strtol("123abc", &pos, 10);
,strtol返回123,pos指向字符串中的字母a。
如果字符串开头没有可识别的整数,
例如char *pos; strtol("ABCabc", &pos, 10);
,则strtol返回0,pos指向字符串开头,可以据此判断这种出错的情况,而这是atoi处理不了的。 -
如果字符串中的整数值超出long int的表示范围(上溢或下溢),则strtol返回它所能表示的最大(或最小)整数,并设置errno为ERANGE,
例如strtol("0XDEADbeef~~", NULL, 16)
返回0x7fffffff并设置errno为ERANGE
用法:
#include <stdlib.h>
#include <stdio.h>
int main()
char *string, *stopstring;
int base;
long l;
string = "-1011 This stopped it";
l = strtol(string, &stopstring, 10);
printf("string = %s\\n", string);
printf("strtol = %ld\\n", l);
printf("Stopped scan at: %s\\n", stopstring);
return 0;
输出:
string = -1011 This stopped it
strtol = -1011
Stopped scan at: This stopped it
1.1.3 字符串转无符号长整型
strtoul
头文件:#include<stdlib.h>
功能 | 把字符串字符串根据参数base来转换成无符号的长整型数 |
---|---|
函数定义 | unsigned long strtoul(const char *nptr,char **endptr,int base) |
参数 | nptr:指向要转换的字符串 endptr:指向停止转换的位置,若字符串nptr的所有字符都成功转换成数字则endptr指向串结束符’\\0’ base:采用的进制方式,如base值为10则采用10进制,若base值为16则采用16进制等。当base值为0时则是采用10进制做转换,但遇到如’0x’前置字符则会使用16进制做转换、遇到’0’前置字符而不是’0x’的时候会使用8进制做转换 |
返回 | 返回转换后的长整型数,否则返回ERANGE并将错误代码存入errno中 |
特点:
同上面strtol函数。
用法:
#include <stdlib.h>
#include <stdio.h>
int main()
int a;
char pNum[]="0xFF";
a=strtoul(pNum,0,0);//最后的0,表示自动识别pNum是几进制
printf("%ul\\n",a);
return 0;
输出:255
1.1.4 字符串转浮点型
atof
头文件:#include<stdlib.h>
功能 | 把字符串转换成浮点数(忽略掉字符串左空格,直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束时(‘\\0’)才结束转换) |
---|---|
函数定义 | double atof(const char *nptr) |
参数 | nptr:指向要转换的字符串(可包含正负号、小数点或E(e)来表示指数部分) |
返回 | 返回转换后的浮点型数 |
用法:
#include <stdlib.h>
#include <stdio.h>
int main(void)
char *a = "-100.23";
char *b = "200e-2";
double c;
c = atof(a)+atof(b);
printf(“c = %.2lf\\n”,c);
return 0;
输出:c = -98.23
strtod
头文件:#include<stdlib.h>
功能 | 把字符串转换成浮点数 |
---|---|
函数定义 | double strtod(const char *nptr,char **endptr) |
参数 | nptr:指向要转换的字符串(可包含正负号、小数点或E(e)来表示指数部分) endptr:指向停止转换的位置,若字符串nptr的所有字符都成功转换成数字则endptr指向串结束符’\\0 |
返回 | 返回转换后的浮点型数 |
用法:
#include <stdlib.h>
#include <stdio.h>
int main()
char *endptr;
char a[] = "12345.6789";
char b[] = "1234.567qwer";
char c[] = "-232.23e4";
printf( "a = %lf\\n", strtod(a,NULL) );
printf( "b = %lf\\n", strtod(b,&endptr) );
printf( "endptr = %s\\n", endptr );
printf( "c = %lf\\n", strtod(c,NULL) );
return 0;
输出:
a = 12345.678900
b = 1234.567000
endptr = qwer
c = -2322300.000000
1.2 数值转字符串
1.2.1 整型转字符串
sprintf
头文件:#include<stdio.h>
功能 | 把格式化的数据写入某个字符串中,结尾自动追加'\\0' 字符 |
---|---|
函数定义 | int sprintf(char *string, char *format [,argument,…]) |
参数 | string:这是指向一个字符数组的指针,该数组存储了 C 字符串 format:这是字符串,包含了要被写入到字符串 str 的文本。它可以包含嵌入的 format 标签,format 标签可被随后的附加参数中指定的值替换,并按需求进行格式化。format 标签属性是%[flags][width][.precision][length]specifier [argument]…:根据不同的 format 字符串,函数可能需要一系列的附加参数,每个参数包含了一个要被插入的值,替换了 format 参数中指定的每个 % 标签。参数的个数应与 % 标签的个数相同 |
返回 | 如果成功,则返回写入的字符总数,不包括字符串追加在字符串末尾的空字符‘\\0’ 。如果失败,则返回一个负数。即,如果“Hello”被写入空间足够大的string后,函数sprintf 返回5。 |
注意:
使用sprintf对于写入buffer的字符数是没有限制的,这就存在了缓冲区溢出
的可能性。解决这个问题,尽量使用”%.ns”
的形式指定最大字符数。或者可以考虑使用snprintf
函数,该函数可对写入字符数做出限制。
用法:
#include <stdio.h>
int main(void)
char buffer[200];
int i = 35;
sprintf(buffer, "%d\\n", i);
printf("integer = %d string = %s\\n", i, buffer);
return 0;
输出:
integer = 35 string = 35
itoa
头文件:#include<stdlib.h>
或#include<cstdlib.h>
功能 | 把整型数转换成字符串 |
---|---|
函数定义 | char *itoa(int value, char *str, int base) |
参数 | value:被转换的整数 str:转换后储存的字符数组 base:转换进制数,如2,8,10,16进制等,大小应在2-36之间 |
返回 | 返回指向str的指针 |
注意:
itoa
并是一个非标准的C/C++函数,它是Windows持有的,如果要写跨平台的程序,请用sprintf
。
用法:
#include <stdlib.h>
//#include <cstdlib>
#include <stdio.h>
//#include <cstdio>
int main(void)
int number=12345;
char string[25];
itoa(number, string, 10);//按10进制转换
printf("integer = %d string = %s\\n", number, string);
itoa(number, string, 16);//按16进制转换
printf("integer = %d string = %s\\n", number, string);
return 0;
输出:
integer = 12345 string = 12345 ——说明12345的十进制表示就是12345
integer = 12345 string = 3039 ——说明12345的十六进制表示是0x3039
1.2.2 长整型转字符串
sprintf
用法同上
ltoa
用法同上
1.2.3 无符号长整型转字符串
sprintf
用法同上
ultoa
用法同上
1.2.4 浮点型转字符串
sprintf
用法同上
gcvt
头文件:#include<stdlib.h>
功能 | 把浮点型数转换为字符串,取四舍五入 |
---|---|
函数定义 | char *gcvt(double value, int ndigit, char *buf) |
参数 | value:被转换的浮点数 ndigit:存储的有效数字位数 buf:转换后储存的字符数组 |
返回 | 返回一个指向结果的存储位置的指针 |
注意:
如果一个缓冲区的尺寸为digits的尺寸+1,该函数覆盖该缓冲区的末尾。这是因为转换的字符串包括一个小数点以及可能包含符号和指数信息。不提供上溢出。gcvt试图以十进制格式产生digits数字,如果不可能,它以指数格式产生digits数字,在转换时可能截除尾部的0。
用法:
#include <stdlib.h>
#include <stdio.h>
int main(void)
char str[25];
double num;
int sig = 5; /* significant digits */
/* a regular number */
num = 9.876;
gcvt(num, sig, str);
printf("string = %s\\n", str);
/* a negative number */
num = -123.4567;
gcvt(num, sig, str);
printf("string = %s\\n", str);
/* scientific notation */
num = 0.678e5;
gcvt(num, sig, str);
printf("string = %s\\n", str);
return(0);
输出:
string = 9.876
string = -123.46
string = 67800
ecvt
头文件:#include<stdlib.h>
功能 | 双精度浮点型数转换为字符串,转换结果中不包括十进制小数点 |
---|---|
函数定义 | char* ecvt(double value, int ndigit, int *decpt, int *sign) |
参数 | value:待转换的双精度浮点数 ndigit:存储的有效数字位数 decpt:存储的小数点位置 sign:转换的数的符号,0为正数,1为负数 |
返回 | 指向生成的字符串 |
注意:
这个函数存储最多ndigit个数字值作为一个字符串,并添加一个空数字符(‘\\0’),如果value中的数字个数超过ndigit,低位数字被舍入。如果少于ndigit个数字,该字符串用0填充。只有数字才存储在该字符串中,小数点位置和value符号在调用之后从decpt和sign获取。decpt参数指出给出小数点位置的整数值, 它是从该字符串的开头位置计算的。0或负数指出小数点在第一个数字的左边。sign参数指出一个指出转换的数的符号的整数。如果该整数为0,这个数为正数,否则为负数。
请尽量使用sprintf
函数做转换。
用法:
#include <stdlib.h>
#include <stdio.h>
int main(void)
char *string;
double value;
int dec,sign;
int ndig = 10;
value = 9.876;
string = ecvt(value, ndig, &dec, &sign);
printf("string=%s dec=%d sign=%d\\n", string, dec, sign);
value = -123.45;
ndig = 15;
string = ecvt(value, ndig, &dec, &sign);
printf("string=%s dec=%d sign=%d\\n", string, dec, sign);
value = 0.6789e5;/*scientificnotation*/
ndig = 5;
string = ecvt(value, ndig, &dec, &sign);
printf("string=%s dec=%d sign=%d\\n", string, dec, sign);
return 0;
输出:
string=9876000000 dec=1 sign=0
string=123450000000000 dec=3 sign=1
string=67890 dec=5 sign=0
fcvt
指定位数为转换精度,其余同ecvt()
二、字节流与数值互转
2.1 字节流转数值
2.1.1 字节流转无符号整型32位
U8ToU32
头文件:#include <stdint.h>
实现:
#include <stdint.h>
/**
@brief uint8_t转换为uint32_t
@param pHexArr -[in] 十六进制数组
@return 无符号整型数值
*/
uint32_t U8ToU32(uint8_t *pHexArr)
return (uint32_t)((pHexArr[0] << 24) + (pHexArr[1] << 16) + (pHexArr[2] << 8) + pHexArr[3]);
用法:
#include <stdio.h>
#include <stdint.h>
int main()
uint8_t arr[4] = 0x01, 0x02, 0x03, 0x04;
uint32_t i = U8ToU32(arr);
printf("hex:0x%x dec:%d\\n", i, i);
return(0);
输出:hex:0x1020304 dec:16909060
2.1.2 字节流转无符号整型16位
U8ToU16
头文件:#include <stdint.h>
实现:
#include <stdint.h>
/**
@brief uint8_t转换为uint16_t
@param pHexArr -[in] 十六进制数组
@return 无符号整型数值
*/
uint16_t U8ToU16(uint8_t *pHexArr)
return (uint16_t)((pHexArr[0] << 8) + pHexArr[1]);
用法:
#include <stdio.h>
#include <stdint.h>
int main()
uint8_t arr[2] = 0x01, 0x02;
uint16_t i = U8ToU16(arr);
printf("hex:0x%x dec:%d\\n", i, i);
return(0);
输出:hex:0x102 dec:258
2.2.1 无符号整型32位转字节流
U32ToU8
头文件:#include <stdint.h>
实现:
#include <stdint.h>
/**
@brief uint32_t转换为uint8_t
@param value -[in] 无符号整型数值
@param pHexArr -[out] 十六进制数组
@return 无
*/
void U32ToU8(uint32_t value, uint8_t *pHexArr)
*(pHexArr + 3) = (uint8_t)(0xFF & value);
*(pHexArr + 2) = (uint8_t)((0xFF00 & value) >> 8);
*(pHexArr + 1) = (uint8_t)((0xFF0000 & value) >> 16);
*(pHexArr) = (uint8_t)((0xFF000000 & value) >> 24);
用法:
#include <stdio.h>
#include <stdint.h>
int main()
uint8_t arr[4];
uint32_t i = 0x11223344;
U32ToU8(i, arr);
printf("%02x %02x %02x %02x\\n", arr[0], arr[1], arr[2], arr[3]);
return(0);
输出:11 22 33 44
2.2.2 无符号整型16位转字节流
U16ToU8
头文件:#include <stdint.h>
实现:
#include <stdint.h>
/**
@brief uint16_t转换为uint8_t
@param value -[in] 无符号整型数值
@param pHexArr -[out] 十六进制数组
@return 无
*/
void U16ToU8(uint16_t value, uint8_t *pHexArr)
*(pHexArr + 1) = (uint8_t)(0xFF & value);
*(pHexArr) = (uint8_t)((0xFF00 & value) >> 8);
用法:
#include <stdio.h>
#include <stdint.h>
int main()
uint8_t arr[2];
uint16_t i = 0x1122;
U16ToU8(i, arr);
printf("%02x %02x\\n", arr[0], arr[1]);
return(0);
输出:11 22
三、字符串与字节流互转
3.1 十六进制字符串转换为字节流
HexStrToBytes
头文件:#include <stdint.h>
和#include <ctype.h>
实现:
#include <stdint.h>
#include <ctype.h>
/**
@brief 十六进制字符串转换为字节流
@param pHexStr -[in] 十六进制字符串
@param hexStrLen -[in] 字符串长度
@param pHexArr -[out] 十六进制数组
@return 无
*/
void HexStrToBytes(const char *pHexStr, uint16_t hexStrLen, uint8_t *pHexArr)
uint16_t i;
uint8_t highByte, lowByte;
for(i = 0; i < hexStrLen; i += 2)
highByte = toupper(pHexStr[i]); // toupper转换为大写字母
lowByte = toupper(pHexStr[i + 1]);
if(highByte > 0x39)
highByte -= 0x37;
else
highByte -= 0x30;
if(lowByte > 0x39)
lowByte -= 0x37;
else
lowByte -= 0x30;
pHexArr[i / 数字前面加负数怎么设置