sprintf函数问题,写入时最后的参数错误

时间:2010-02-19 21:15:50

标签: 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的长度限制?

我检查了所有数字的类型,它们是正确的,但似乎问题是dDistance。当我从sprint中删除它时,nConfig在字符串中获得正确的值,但是当我删除nConfig时,dDistance仍然没有得到正确的值。我查了一下,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

4 个答案:

答案 0 :(得分:5)

我会检查以确保您的参数类型与您的格式字符串元素匹配。尝试将double显示为整数类型(%d)或反之亦然可以为您提供奇怪的输出。

答案 1 :(得分:2)

您确定您的数据类型符合您的格式规范吗?

尝试打印出您的数据,即创建一个格式相同的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做一些事情;

答案 2 :(得分:1)

什么尺寸长和int?

如果nID是长期打印的'int'格式并且sizeof(int)!= sizeof(long)那么你从那里得到错位的数据访问(在对齐方式不正确的意义上)。

您使用的是哪种编译器?如果麻烦的话,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);
}

我得到了我期望的输出:

2|35.000000|0

要获得您显示的输出,您必须使用非常奇怪的设置。

  • 你在哪个平台?

您显示的行为表明您正在使用的sprintf()函数对某些内容的对齐或大小感到困惑。你有范围的原型 - 也就是说,你有#included <stdio.h>吗?使用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更改为long double,那么我会得到一组不同的警告和不同的结果:

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.但我还是有点不知所措你得到你所展示的东西 - 除非你是在一台大端机器上(我正在使用MacOS X 10.6.2在Intel Mac上进行测试)... 暂停 ...在运行的SPARC机器上运行Solaris 10,没有#include <stdio.h>long double test2 = 35.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

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

那么,您可以发布显示问题的可编译代码,而不是不支持的代码段吗?您能否确定您的平台 - 机器类型,操作系统版本,编译器版本(以及可能的C库版本)?

答案 3 :(得分:0)

dDistance是double型吗?看起来你的%f只抓取一个double的四个字节然后接下来的四个字节被视为一个整数,然后忽略实际的整数值。

这个问题标记为C ++;你能使用std :: ostringstream来消除转换字符串的任何可能问题吗?