sprintf中关于返回'%'字符的歧义

时间:2019-01-05 22:39:54

标签: c printf

我必须输出一个以%字符(%EE#WD ...)开头的字符串,并且我正在使用sprintf。在多个参考文献中,我读到在%说明符后面使用%会导致sprintf函数返回%字符。

但是对我来说,在不同的编译器(例如DEV C ++,JDOODLE)中,结果不是我期望的,最后我通过重复%指定符4次获得了%字符!

是什么原因?

以下是代码和输出:

#include <stdio.h>
int main()
{
    static char Command[10]   ;
    sprintf (Command,"%%EE#") ;
    printf  (Command)         ;    
    return 0                  ;
}

输出: 3.205269E-317E#

#include <stdio.h>
int main()
{
    static char Command[10]     ;
    sprintf (Command,"%%%%EE#") ;
    printf  (Command)           ;    
    return 0                    ;
}

输出: %EE#

谢谢。

4 个答案:

答案 0 :(得分:4)

sprintf (Command,"%%EE#")之后,Command将包含%EE#。如果现在将此内容作为格式字符串传递给printf,则(现在)单%将被解释为格式说明符,然后寻找一个float参数。没有提供,实际上导致不确定的行为。使用sprintf (Command,"%%%%EE#"),您可以“克服”此问题,因为Command将包含%%EE#

但是实际上您应该写...

static char Command[10] = "%EE#";
printf  ("%s",Command);    

或者...

static char Command[10];
strcpy(Command,"%EE#");
printf  ("%s",Command);    

答案 1 :(得分:3)

sprintf的结果作为第一个参数传递给printf会使它重新解释为格式字符串。因此,一次将您的字符串解释为格式字符串,sprintf,然后再次解释为printf。不要这样做。

如果不需要格式化,只需使用fputs打印一个字符串,就像fputs("%EE#", stdout);一样。 ({puts类似,但它附加了换行符。fputs仅打印给出的字符。)

如果需要格式化并且可以直接打印(没有中间缓冲区),请使用printf;请勿事先使用sprintf

如果需要格式化并将结果写入缓冲区,请使用sprintf并使用fputs而不是printf打印缓冲区。

答案 2 :(得分:1)

sprintf (Command,"%%EE#") ;
printf  (Command)         ;    

%% 格式是要求打印的方式,因此 %% EE#会产生%EE#

因此,正如邢在评论中所说的那样, printf(command)适用于%EE#,就像直接执行 printf(“%EE#”)一样,并且缺少arg,因此“%E”的结果是随机的

sprintf (Command,"%%%%EE#") ;
printf  (Command)           ;  

sprintf 设置命令为“ %% EE#”,这样在您获得printf("%%EE#")为%EE#

的结果之后

答案 3 :(得分:0)

%%会给您% %E实际上是指科学计数法,这就是为什么您要获取数字并需要更多%才能打印出%E < / p>