我只是尝试使用sprintf连接一些字符串,但我有这个问题, 我不明白为什么我的程序在C中使用sprintf崩溃了。为什么这个代码会运行?
#include <stdio.h>
#include <stdlib.h>
int main()
{
char* dateTime = malloc(16*sizeof(char));
printf("Date: %s\n", __DATE__);
printf("Time: %s\n", __TIME__);
sprintf (dateTime, "%s, %s\0", __DATE__, __TIME__);
printf("%s", dateTime);
free(dateTime);
return 0;
}
这不是吗?
#include <stdio.h>
#include <stdlib.h>
int main()
{
char* dateTime = malloc(16*sizeof(char));
//printf("Date: %s\n", __DATE__);
//printf("Time: %s\n", __TIME__);
sprintf (dateTime, "%s, %s\0", __DATE__, __TIME__);
printf("%s", dateTime);
free(dateTime);
return 0;
}
答案 0 :(得分:7)
在我的编译器上,您创建的字符串长度为21个字符(Dec 23 2016, 23:29:57
),因此您基本上为字符串分配了太少的字节。
您获得了未定义的行为。所以它在没有printf
语句的情况下崩溃,并且与它们一起工作,因为计算机没有做同样的事情,但它仍然是错误的。
顺便说一下,你可以通过这样做来安全地实现你想要的东西:
const char *dateTime= __DATE__ " " __TIME__;
因为__DATE__
和__TIME__
已经是字符串宏。预处理器可以在编译时进行连接。
如果您想计算所需的字符数,可以将snprintf
与NULL
缓冲区一起使用(仅限c99):
使用零bufsz和缓冲区空指针调用snprintf对于确定包含输出所需的缓冲区大小很有用:
const char *fmt = "sqrt(2) = %f";
int sz = snprintf(NULL, 0, fmt, sqrt(2));
char buf[sz + 1]; // note +1 for terminating null byte
snprintf(buf, sizeof buf, fmt, sqrt(2));
答案 1 :(得分:4)
对于sprintf
,您的缓冲区似乎太小了:
char* dateTime = malloc(16*sizeof(char));
__DATE__
和__TIME__
总是占用超过15个字节(不包括NUL字符)。写入数组边界会导致未定义的行为。