C 为什么这个程序会崩溃?
此函数应返回一个字符串,该字符串包含第二个和后续参数的字符串表示形式,每个参数保留两位小数,并用逗号分隔。第一个参数是随后参数数量的计数。我做了一些研究,发现了C 为什么这个程序会崩溃?,c,variables,arguments,C,Variables,Arguments,此函数应返回一个字符串,该字符串包含第二个和后续参数的字符串表示形式,每个参数保留两位小数,并用逗号分隔。第一个参数是随后参数数量的计数。我做了一些研究,发现了va_list,并尝试使用它。不幸的是,程序正在崩溃,我不知道为什么。我发这篇文章是希望有人能发现一个明显的错误或类似的东西 #include <stdio.h> #include <stdlib.h> #include <stdarg.h> char *to_string(int count,...
va_list
,并尝试使用它。不幸的是,程序正在崩溃,我不知道为什么。我发这篇文章是希望有人能发现一个明显的错误或类似的东西
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
char *to_string(int count,...)
{
int i,x,k=0;
float tmp;
va_list valist;
va_start(valist, count+1);
char comma=',';
char buffer[count*6];
for(i=0;i<count;i++)
{
tmp=va_arg(valist, double)*100;
x=tmp/100.0;
k+=4;
snprintf(buffer + k, "%C",comma);
k++;
snprintf(buffer + 1, "%.2f", x);
}
va_end(valist);
printf("%s", buffer);
return buffer;
}
int main()
{
to_string(2,3.14876,6.123243);
}
#包括
#包括
#包括
字符*到字符串(整数计数,…)
{
int i,x,k=0;
浮动tmp;
va_列表valist;
va_开始(最有效,计数+1);
字符逗号=',';
字符缓冲区[计数*6];
对于(i=0;i,如注释中所述,您需要阅读和的手册页,特别是,还需要注意内存管理(您不能安全地返回指向本地(非静态
)变量的指针)
这是一段经过修改的代码,它可以清除已识别的问题,并且不会崩溃(对于我在运行macOS Sierra 10.12.1和GCC 6.2.0的Mac上的情况)
请注意,有一个可能不需要的前导逗号。可以这样修复:
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
static char *to_string(char *buffer, size_t buflen, int count, ...)
{
va_list valist;
va_start(valist, count);
char *data = buffer;
const char *pad = "";
for (int i = 0; i < count; i++)
{
int x = va_arg(valist, double) * 100;
double tmp = x / 100.0 + 0.005;
int n = snprintf(data, buflen, "%s%.2f", pad, tmp);
if (n > (int)(buflen - 1))
{
fprintf(stderr, "%s: buffer not big enough\n", __func__);
break;
}
pad = ",";
data += n;
buflen -= n;
}
va_end(valist);
printf("%s: [%s]\n", __func__, buffer);
return buffer;
}
int main(void)
{
char buffer[80];
printf("main: [%s]\n", to_string(buffer, sizeof(buffer), 2, 3.14876, 6.123243));
printf("main: [%s]\n", to_string(buffer, sizeof(buffer), 20,
6.67, 0.04, 8.81, 8.49, 3.50, 1.20, 4.28, 0.67, 1.93, 5.63,
5.30, 8.43, 1.99, 4.62, 5.54, 7.21, 9.43, 2.02, 4.77, 0.29));
return 0;
}
returnbuffer;
用于失效的局部变量。未定义的行为。va_start(valist,count+1);
应该是va_start(valist,count);
。重新阅读的规范。奇怪的是,OP没有使用函数返回值。语句对tmp=va_arg(valist,double)*100;x=tmp/100.0;
很奇怪;我看不出它与x=va_arg(valist,double)有什么不同
这更容易理解。增量k+=4;
是不成熟的;这意味着数组的前4个字节未初始化。使用%C
是一个POSIX ish扩展,相当于%lc
,但逗号
不是wchar\t
(但您可能不会受到影响,因为char
被提升为int
,因为它用于printf()
的尾随参数。您对snprintf()
的调用有缺陷,因为您将格式字符串作为长度传递。int-snprintf(char*restrict s,size\u t n,const char*restrict format,…)
谢谢。我只想指出,它不应该像3.14876那样对数字进行四舍五入,它会四舍五入到3.15.OK;然后不要添加0.005。
to_string: [,3.15,6.12]
main: [,3.15,6.12]
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
static char *to_string(char *buffer, size_t buflen, int count, ...)
{
va_list valist;
va_start(valist, count);
char *data = buffer;
const char *pad = "";
for (int i = 0; i < count; i++)
{
int x = va_arg(valist, double) * 100;
double tmp = x / 100.0 + 0.005;
int n = snprintf(data, buflen, "%s%.2f", pad, tmp);
if (n > (int)(buflen - 1))
{
fprintf(stderr, "%s: buffer not big enough\n", __func__);
break;
}
pad = ",";
data += n;
buflen -= n;
}
va_end(valist);
printf("%s: [%s]\n", __func__, buffer);
return buffer;
}
int main(void)
{
char buffer[80];
printf("main: [%s]\n", to_string(buffer, sizeof(buffer), 2, 3.14876, 6.123243));
printf("main: [%s]\n", to_string(buffer, sizeof(buffer), 20,
6.67, 0.04, 8.81, 8.49, 3.50, 1.20, 4.28, 0.67, 1.93, 5.63,
5.30, 8.43, 1.99, 4.62, 5.54, 7.21, 9.43, 2.02, 4.77, 0.29));
return 0;
}
to_string: buffer not big enough
to_string: [3.15,6.12]
main: [3.15,6.12]
to_string: [6.67,0.04,8.82,8.50,3.50,1.20,4.29,0.68,1.93,5.63,5.30,8.44,1.99,4.62,5.54,7.21]
main: [6.67,0.04,8.82,8.50,3.50,1.20,4.29,0.68,1.93,5.63,5.30,8.44,1.99,4.62,5.54,7.21]