Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么这个程序会崩溃?_C_Variables_Arguments - Fatal编程技术网

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]