C语言里有这么一个比较简单的程序,明显是写错了,我想找找,但是没看懂是什么意思。我相信控制台的输出应该是 str: 102 num: 1025
输出:str:1025 num:1024
为什么 num 在 sprintf 之后发生变化?以及为什么在函数内部调试时写入str而不是3位,'1','0','2'存储在str中,输出为1025。我试图从%3d更改说明符到 %d,结果没有改变。
#include <stdio.h>
typedef struct
{
char str[3];
int num;
} NumberRepr;
void format(NumberRepr* number)
{
sprintf(number->str, "%3d", number->num);
}
int main()
{
NumberRepr number = { .num = 1025 };
format(&number);
printf("str: %s\n", number.str);
printf("num: %d\n", number.num);
return 0;
}
因为您忘记了 C 字符串 (array
char
) 是一个以 null 结尾的字符串。结果,当您以 3 个字节编写字符串时%3d
,第四个字符 - 零 - 将进一步写入内存并破坏结构的下一个字段。您需要指定一个不同的、足够大小的数组。好吧,例如,您不能将数字 1024 放在 3 个字符中(它需要 5 个)。总而言之,不要上当。
尽管为什么您需要同时以不同的形式保留相同的数字-我不太明白。但是从 int 可以是负 20 亿的事实出发,即
char str[12]
至少真的需要...显然您还没有阅读.
sprintf
格式字符串中的数字 3 指定最小字段宽度。因此,要使用 format%3d
和 format打印数字 1025,%d
需要 4 + 1 个字节。无论哪种方式,都会发生缓冲区溢出。相反,您应该使用一个函数snprintf
并指定传入缓冲区的大小。您还应该记住检查错误或输出截断的返回值:在线编译器
另外,缓冲区大小不应该是硬编码的,而是通过宏来确定的,但这是另一个问题。