C++ sprintf函数存在问题,写入最后一个参数时出错

C++ sprintf函数存在问题,写入最后一个参数时出错,c++,c,printf,C++,C,Printf,所以我使用sprintf sprintf(buffer, "%f|%f|%f|%f|%f|%f|%d|%f|%d", x, y, z, u, v, w, nID, dDistance, nConfig); 但是当我打印缓冲区时,我得到的最后两个参数是错误的,假设它们是35.0000和0,在字符串中它们是0.00000和10332430,我的缓冲区足够长,字符串中的所有其他参数都很好 有什么想法吗?sprintf或其他东西有长度限制吗 我检查了所有数字的类型,它们都是正确的,但问题似乎在于数据的

所以我使用sprintf

sprintf(buffer, "%f|%f|%f|%f|%f|%f|%d|%f|%d", x, y, z, u, v, w, nID, dDistance, nConfig);
但是当我打印缓冲区时,我得到的最后两个参数是错误的,假设它们是35.0000和0,在字符串中它们是0.00000和10332430,我的缓冲区足够长,字符串中的所有其他参数都很好

有什么想法吗?sprintf或其他东西有长度限制吗

我检查了所有数字的类型,它们都是正确的,但问题似乎在于数据的位置。当我从sprint中删除它时,nConfig会在字符串中获得正确的值,但是当我删除nConfig时,dDistance仍然没有获得正确的值。我检查了一下,发现是双精度的。有什么想法吗

因为人们似乎不相信我,所以我这样做了:

char test[255]={0};
int test1 = 2;
double test2=35.00;
int test3 = 0;

sprintf(test,"%d|%f|%d",test1,test2,test3);
我在我的字符串中得到了这个:

2|0.000000|1078034432

我会检查以确保参数类型与格式字符串元素匹配。尝试将double显示为整数类型%d或将double显示为整数类型%d会产生奇怪的输出。

您确定数据类型与格式规范匹配吗

尝试打印数据,即创建一个具有相同格式的printf,看看会发生什么:

printf("%f|%f|%f|%f|%f|%f|%d|%f|%d", x, y, z, u, v, w, nID,dDistance, nConfig);
例如,尝试使用流

stringstream ss;

ss << x << "|" << y << "|" << z << "|" << u << "|" << v << "|" << w << "|"
   << nID << "|"<< dDistance << "|"<< nConfig;

string s = ss.str();

然后用s做点什么

长和int的大小是多少

如果nID是一个长文件,则使用“int”格式和sizeofint!=SizeOfflong然后您将获得未对齐的数据访问,从这个意义上说,对齐从那时起是不正确的

您使用的是哪种编译器?如果是问题,GCC应该毫不费力地诊断问题。类似地,如果nID是“long-long”,您可能会遇到问题

回答您的问题-是的,sprintf必须能够处理字符串长度上限的下限。C89系统为509,C99系统为4095

准确地说,C99表示fprintf,第7.19.6.1节,第15段:

任何一次转换可产生的字符数应至少为 4095

sprintf没有进一步的资格认证

将修订示例的固定版本转换为可编译代码:

#include <stdio.h>
int main(void)
{
    char  test[255] = {0};
    int    test1 = 2;
    double test2 = 35.00;
    int    test3 = 0;
    sprintf(test, "%d|%f|%d", test1, test2, test3);
    puts(test);
    return(0);
}
要获得显示的输出,必须使用非常奇怪的设置

你在哪个站台? 您显示的行为表明您正在使用的sprintf函数对某个对象的对齐方式或大小感到困惑。你是否有一个范围内的原型-也就是说,你是否包括在内?使用GCC,当我忽略标题时,会收到各种警告:

x.c: In function ‘main’:
x.c:8: warning: implicit declaration of function ‘sprintf’
x.c:8: warning: incompatible implicit declaration of built-in function ‘sprintf’
x.c:9: warning: implicit declaration of function ‘puts’
但即使将test2重新定义为float,我也得到了正确的结果

如果我将test2更改为长双精度,则会得到不同的警告集和不同的结果:

x.c: In function ‘main’:
x.c:8: warning: implicit declaration of function ‘sprintf’
x.c:8: warning: incompatible implicit declaration of built-in function ‘sprintf’
x.c:8: warning: format ‘%f’ expects type ‘double’, but argument 4 has type ‘long double’
x.c:9: warning: implicit declaration of function ‘puts’

2|0.000000|0
这更接近于你所看到的,尽管远非完全相同

因为我们没有平台信息,我怀疑你是在和一个真正的古董合作,还是我指的是马车?C的版本。但我还是有点不知所措,不知道你是如何得到你展示的东西的-除非你是在一台big-endian机器上,我正在用MacOS X 10.6.2在英特尔Mac上测试…暂停。。。在运行Solaris 10的SPARC计算机上,不带include且具有长双测试2=35.0;,我得到:

那是不同的;它还生成321个字符的输出,因此其中存在缓冲区溢出-最好使用“snprintf”来防止这种情况发生。当然,当事情被正确地声明时,我会得到预期的结果


那么,您是否可以发布显示问题的可编译代码,而不是不显示问题的代码片段?您能识别您的平台机器类型、操作系统版本、编译器版本以及可能的C库版本吗?

是double类型的实例吗?看起来您的%f只获取了一个double的四个字节,然后接下来的四个字节被视为一个整数,实际的整数值将被忽略


这个问题是用C++来标注的;您是否能够使用std::ostringstream来消除转换字符串可能出现的任何问题?

对不起,您是否检查了值是否正确?很难评论。发布复制此问题的最小可编译源代码。至少,尝试在控制台上打印这些值。检查sprintf的返回值。如果您尝试仅sprintf输出最后两个参数,会发生什么情况?x、y、z等的类型是什么?为什么不在调试器中单步执行对sprintf的调用,看看它在做什么?这有点枯燥,但结果通常很有启发性。除nID和nConfig为int外,其他都是double。从最新更新来看,如果将35.0转换为IEEE double,则会得到位模式0x107803432000000000。如果只取前四个字节,它恰好以整数形式转换为1078034432,这仅适用于体系结构为little endian的情况。在您的测试程序中,尝试%lf而不是%f,以查看您的库是否没有正确处理%f-to-double格式。它们匹配,但当我尝试交换时,让我们说
第一个和最后一个交换%f和%d,我得到了正确的字符串。我不明白你的意思,请进一步解释?如果我用nconfig交换x并将%f和%d放在各自的位置,我得到了正确的字符串。那么你是说这条语句有效吗?printf%d |%f |%f |%f |%f |%f |%d |%f |%f,nConfig,y,z,u,v,w,nID,dDistance,x;因为/那/听起来好像你在什么地方打错了字
x.c: In function ‘main’:
x.c:8: warning: implicit declaration of function ‘sprintf’
x.c:8: warning: incompatible implicit declaration of built-in function ‘sprintf’
x.c:8: warning: format ‘%f’ expects type ‘double’, but argument 4 has type ‘long double’
x.c:9: warning: implicit declaration of function ‘puts’

2|0.000000|0
gcc -O x.c -o x && ./x 
x.c: In function 'main':
x.c:8: warning: incompatible implicit declaration of built-in function 'sprintf'
2|-22446048024026502740613283801712842727785152907992454451420278635613183447049251888877319095301502091725503415850736723945766334416305449970423980980099172087880564051243997662107950451281495566975073444407658980167407319222477077473080454782593800009947058951029590025152409694784570786541673131117073399808.000000|0