数据类型转换和格式化打印
1、数据类型转换
数据类型的转换是指将一个数据类型的值转换为另一个数据类型的值。在编程中,我们可能需要将一个整数转换为浮点数、将一个字符串转换为数字等等。这种转换通常涉及到一些算术或逻辑操作,以及数据类型的隐式或显式转换
2、格式化打印
格式化打印是指将一个或多个变量的值格式化为一个字符串,以便输出到屏幕或文件中。格式化打印通常涉及到一些字符串操作,如字符串拼接、字符串替换、格式控制符等。格式化打印的目的是将数据以一种易于阅读的方式呈现给用户,可以包括数字、文本、日期等数据类型。
按照不同的格式打印数据
C语言中可以使用printf函数的格式控制符来进行16进制格式打印。下面是常用的格式控制符:
- %x 或 %X:用于以16进制格式打印一个整数。小写字母x表示输出16进制数字为小写字母(af),大写字母X表示输出16进制数字为大写字母(AF)。
- %#x 或 %#X:与%x或%X相同,但会在输出结果前加上“0x”或“0X”前缀。
- %hx 或 %hX:用于以16进制格式打印一个short类型整数(即16位整数)。
- %#hx 或 %#hX:与%hx或%hX相同,但会在输出结果前加上“0x”或“0X”前缀。
- %lx 或 %lX:用于以16进制格式打印一个long类型整数(即32位整数)。
- %#lx 或 %#lX:与%lx或%lX相同,但会在输出结果前加上“0x”或“0X”前缀。
示例:
#include <stdio.h>
int a = 255;
int b = 0x7fff;
int c = 0x12345678;
int main(void)
{
printf("a = %d\r\n",a);
printf("a = %x\r\n",a);
printf("a = %X\r\n",a);
printf("a = %#X\r\n",a);
printf("a = %hX\r\n",a);
printf("a = %lX\r\n",a);
printf("b = %d\r\n",b);
printf("b = %x\r\n",b);
printf("c = %d\r\n",c);
printf("c = %x\r\n",c);
return 0;
}
[result]
a = 255
a = ff
a = FF
a = 0XFF
a = FF
a = FF
b = 32767
b = 7fff
c = 305419896
c = 12345678
不同的打印格式表示的都是同一个数字,只不过就是格式不同罢了。
将字符串中的
字符
转换为对应的十进制(或者十六进制)的整数数值
/**
*@brief 将 ASCII 字符转换为十六进制数值(或者十进制数值)
*@param c: 要转换的字符
*@return 返回:返回一个 char 类型的值,表示对应的十六进制数值(或者十进制数值)
*/
char c2d(uint8 c)
{
if (c >= '0' && c <= '9') // 如果是数字字符
return c - '0'; // 直接转换为数字
if (c >= 'a' && c <= 'f') // 如果是小写字母
return 10 + c -'a'; // 转换为数字(a~f对应10~15)
if (c >= 'A' && c <= 'F') // 如果是大写字母
return 10 + c -'A'; // 转换为数字(A~F对应10~15)
return (char)c; // 其他字符返回本身
}
c2d
主要是针对单个字符操作的,输出的也是单个的结果,一一对应,因此不能直接对字符串操作,针对的是单字符。在对字符串操作的时候,需要使用指针取出单个的字符操作。
示例:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
int main()
{
char hex_str[] = "1aF3";
uint8_t hex_len = sizeof(hex_str) - 1; // 计算字符串长度
uint16_t hex_num[hex_len]; // 定义存储十六进制数字的数组
// 把每个字符转换为对应的十六进制数字
for (int i = 0; i < hex_len; i++) {
hex_num[i] = c2d(hex_str[i]);
}
// 输出转换后的数字
for (int i = 0; i < hex_len; i++)
{
printf("%04x ", hex_num[i]); //打印对应的十六进制样式展示的数据
}
printf("\r\n");
for (int i = 0; i < hex_len; i++)
{
printf("%d ", hex_num[i]); //打印对应的十进制样式展示的数据
}
return 0;
}
[result]
0001 000a 000f 0003
1 10 15 3
倘若将其中的”1aF3“换成”1aZ3“的话就无法转换 不复合十六进制类型要求的范围
将整数
字符串
转换成整数(十进制样式或者十六进制样式)
int atoi(const char *str)
描述 | C 库函数 int atoi(const char *str) 把参数 str 所指向的字符串转换为一个整数(类型为 int 型)。 |
---|---|
声明 | int atoi(const char *str),在#include <stdlib.h>函数中调用 |
参数 | str – 要转换为整数的字符串。 |
返回值 | 该函数返回转换后的长整数,如果没有执行有效的转换,则返回零。 |
atoi
是英文array to integer
的缩写。atoi()
会扫描参数str
字符串,如果第一个字符不是数字也不是正负号返回零,否则开始做类型转换,之后检测到非数字或结束符/0
时停止转换,返回整型数。
示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int val;
char str1[20] = "1122334";
char str2[20] = "baidu";
int main(void)
{
val = atoi(str1);
printf("val = %d\r\n",val);
printf("val = %#x\r\n",val);
val = atoi(str2);
printf("val = %d\r\n",val);
return 0;
}
[result]
val = 1122334
val = 0x11201e
val = 0
只针对十进制类型数值进行转换,直接转换成十进制数值(或者十六进制样式),这个转换的是字符对整数。
十六进制格式的字符串转换成十进制
描述 | C 库函数 long int strtol(const char *str, char **endptr, int base) 把参数 str 所指向的字符串根据给定的 base 转换为一个长整数(类型为 long int 型),base 必须介于 2 和 36(包含)之间,或者是特殊值 0。 |
---|---|
声明 | long int strtol(const char *str, char **endptr, int base) |
参数 | str – 要转换为长整数的字符串。 endptr – 对类型为 char* 的对象的引用,其值由函数设置为 str 中数值后的下一个字符。 base – 基数,必须介于 2 和 36(包含)之间,或者是特殊值 0。 |
返回值 | 该函数返回转换后的长整数,如果没有执行有效的转换,则返回一个零值。 |
示例1:
#include <stdio.h>
#include <stdlib.h>
int main() {
char* hex_str = "1A7F"; // 十六进制格式的字符串
long decimal = strtol(hex_str, NULL, 16); // 调用strtol()函数将十六进制字符串转换为十进制整数
printf("Hexadecimal: %s\n", hex_str);
printf("Decimal: %ld\n", decimal);
return 0;
}
[result]
Hexadecimal: 1A7F
Decimal: 6783
示例2:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char str[30] = "2030300 This is test";
char *ptr;
long ret;
ret = strtol(str, &ptr, 10);
printf("数字(无符号长整数)是 %ld\n", ret);
printf("字符串部分是 |%s|", ptr);
return(0);
}
[result]
数字(无符号长整数)是 2030300
字符串部分是 | This is test |
将一个长整型数(long)转换成一个字符串
char* ltoa(long num, char* str, int base);
- "num"是要转换的长整型数;
- "str"是一个字符数组,用于存储转换后的字符串;
- "base"是转换的基数,可以是2、8、10或16。
函数将长整型数"num"转换成基数为"base"的字符串,并将结果存储在"str"中。如果转换成功,该函数返回"str"的指针,否则返回NULL。
示例:
#include <stdio.h>
#include <stdlib.h>
int main() {
long num = 123456789;
char str[20];
ltoa(num, str, 10); // 将长整型数转换成十进制字符串
printf("Long integer: %ld\n", num);
printf("String: %s\n", str);
return 0;
}
[result]
Long integer: 123456789
String: 123456789
修改后的
atoi()
函数 修改为myatoi()
使用注意:
atoi()
返回的数据类型是int类型
,因此就是在转换的时候str
不能超出范围- 该函数在转换的时候会跳过空格,当遇到数字、正负号后才开始转换
- 最后遇到结束标志符号
\0
结束
// 这个函数接收一个字符串作为输入,并将其转换为整数值
// 然后将整数值返回
// 字符串必须只包含数字字符,或者以符号字符开头
/*调整uint8_t 为int 则可以获得更大的数据转换 uint8_t 只能转换0-255*/
uint8_t myatoi(const char *str)
{
int s = 0; // 要返回的整数值
uint8_t flag = 0; // 用于跟踪数字是否为负数
// 忽略前导空格
while (*str == ' ')
{
str++;
}
// 检查数字是否为负数或正数
if (*str == '-' || *str == '+')
{
if (*str == '-')
flag = 1; // 将标志设置为负数
str++; // 将指针移动到符号字符的下一个字符
}
// 将数字字符转换为整数值
while (*str >= '0' && *str <= '9')
{
// 将当前值乘以10,然后加上当前数字的值
s = s * 10 + (*str - '0');
str++; // 将指针移动到下一个字符
if (s < 0) // 检查是否溢出
{
s = 2147483647; // 将值设置为最大整数值
break; // 退出循环
}
}
// 返回整数值,根据需要考虑符号
return s * (flag ? -1 : 1);
}
示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
uint16_t myatoi(const char *str)
{
int s = 0;
uint8_t falg = 0;
while(*str==' ')
{
str++;
}
if(*str=='-'||*str=='+')
{
if(*str=='-')
falg=1;
str++;
}
while(*str>='0'&&*str<='9')
{
s=s*10+*str-'0';
str++;
if(s<0)
{
s=2147483647;
break;
}
}
return s*(falg?-1:1);
}
char str[] = "65535";
uint16_t num = 0;
int main(void)
{
num = myatoi(str);
printf("num = %d\r\n",num);
return 0;
}
[result]
num = 65535