C 字符串格式在fprintf中工作,但在sprintf中不工作,导致分段错误

C 字符串格式在fprintf中工作,但在sprintf中不工作,导致分段错误,c,segmentation-fault,printf,C,Segmentation Fault,Printf,您好,正如您所看到的,在上面的语句中,我试图从包含整个http数据包数据的char指针中注销User代理头。问题是,在摆弄了字符串格式之后,我提出了这个%.*s格式,它允许我动态选择要打印到文件中的字符数,然后打印它们。代码基本上是这样做的,首先,它打印一个int,然后传递从出现User Agent:到下一次出现的新行字符的字符数,然后从User Agent:开始的位置开始,从整个数据包数据字符串传递该字符数。我知道这一切都很混乱,但它工作得很好。除了它在sprintf中不起作用 请保存我所有的

您好,正如您所看到的,在上面的语句中,我试图从包含整个http数据包数据的char指针中注销User代理头。问题是,在摆弄了字符串格式之后,我提出了这个%.*s格式,它允许我动态选择要打印到文件中的字符数,然后打印它们。代码基本上是这样做的,首先,它打印一个int,然后传递从出现User Agent:到下一次出现的新行字符的字符数,然后从User Agent:开始的位置开始,从整个数据包数据字符串传递该字符数。我知道这一切都很混乱,但它工作得很好。除了它在sprintf中不起作用

请保存我所有的硬词!感谢您的帮助

fprintf(fp,"IP: %d:  %.*s\n",
        ip, 
        strstr(strstr(p->data, "User-Agent:"),"\n") - strstr(p->data, "User-Agent:"),
        strstr(p->data, "User-Agent: ") );
    fclose(fp);

使用sprintf时,需要写入一个字符数组。您正在向未初始化的指针写入

请尝试以下方法:

    char *stat;
    sprintf(stat,"%.*s\0",
        strstr(strstr(p->data, "User-Agent:"),"\n") - strstr(p->data, "User-Agent:"),
        strstr(p->data, "User-Agent: ")) ;

您没有为stat分配内存。请重试


您正试图将数据写入未初始化的未分配随机内存位置。这不可能奏效

或者:

char *stat = malloc(MAXLEN);
snprintf(stat, MAXLEN, ...);
 ^              ^
或:

并确保足够大的字节数足以容纳字符串,而不是不必要的大


PS:snprintf,因为您的格式不包括长度限制。如果是这样,sprintf是可以的,但永远不要将sprintf与无限的%s一起使用。您的%.*s虽然受到形式上的限制,但还不够,因为表达式返回的值将超过分配的缓冲区的大小,因此您需要进行另一次检查以避免溢出。

对于使用相同参数调用同一strstr 3次,您感到羞耻。你知道,这是一个相当昂贵的功能。@Jan:但话说回来,过早的优化是万恶之源。不这样编写复制粘贴代码的一个更好的理由是,它的健壮性较低,而且更难维护。@Paul R:是的,可维护性也是一个很好的理由。至于过早优化,为了未经证实的好处,过早优化会使代码更加复杂,但这会使代码更简单、更可读;char*ua_end=strchrua_start,'\n';sprintfstat,%.*s\0,ua\U end-ua\U start,ua\U start;未测试。如果您修复此代码,使其在标头格式错误时不会崩溃,则需要对strstr进行更慢、更难看、更大的调用来进行检查。为了Cthulu的缘故,请制作一些适当的温度变量来存储所需的位置/长度!我认为数组和char指针是一样的,只要把它传递给函数就行了。这就是为什么我这么做了,但我意识到了这一点,并最终纠正了它。我就是这样做的,甚至选择了同样的数字200。谢谢你的解释,还有sprintf和snprintf。我从来不知道snprint的存在。谢谢你的帮助!
char *stat = malloc(MAXLEN);
snprintf(stat, MAXLEN, ...);
 ^              ^
char stat[SUFFICIENTLY_LARGE_NUMBER];
snprintf(stat, SUFFICIENTLY_LARGE_NUMBER, ...);
char *stat = malloc(SUFFICIENTLY_LARGE_NUMBER);
snprintf(stat, SUFFICIENTLY_LARGE_NUMBER, ...);