Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > sprintf behavies different than printf

Reply
Thread Tools

sprintf behavies different than printf

 
 
google@pekspro.com
Guest
Posts: n/a
 
      03-14-2008
Consider the following code:

char str[100];
char str2[100];
strcpy(str, "%alfa% %beta% d%100%d %gamma% %delta%");
printf("printf: ");
printf("1%s2", str);
printf("\nsprintf: ");
sprintf(str2, "1%s2", str); //Interesting stuff happens here
printf(str2);
printf("\n");

The code should format the string "1%s2" by replacing %s with "%alfa%
%beta% d%100%d %gamma% %delta%". First printf is used, and then
sprintf. The output should be:

printf: 1%alfa% %beta% d%100%d %gamma% %delta%2
sprintf: 1%alfa% %beta% d%100%d %gamma% %delta%2

However, this is not what happens i either Visual C++ 6.0, Visual C++
2003 and GCC (version 4 I think, compiled and tested in Linux). In all
these compilers printf works as expected, but fails with sprintf where
the result is either a crash or a malformed string. The problem seems
to be that the %-character is used in the argument which, as fair as I
know, shouldn't be any problem.

If I replace %s with "%%alfa%% %%beta%% d%%100%%d %%gamma%% %%delta%%"
the output will instead by (at least in Visual C++ 2003):

printf: 1%%alfa%% %%beta%% d%%100%%d %%gamma%% %%delta%%2
sprintf: 1%alfa% %beta% d%100%d %gamma% %delta%2

So when using sprintf %% is replaced by % which should be the is these
characters where written in the format string, but this is a very
different case.

Unless I have misunderstand the specification of sprintf there is a
quite critical bug in sprintf and this in several compilers. Is this
an known problem? Are more compilers affected? Why are the problem in
both Visual C++ and GCC? Isn't this very interesting?

PEK
 
Reply With Quote
 
 
 
 
Eric Sosman
Guest
Posts: n/a
 
      03-14-2008
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> Consider the following code:
>
> char str[100];
> char str2[100];
> strcpy(str, "%alfa% %beta% d%100%d %gamma% %delta%");
> printf("printf: ");
> printf("1%s2", str);
> printf("\nsprintf: ");
> sprintf(str2, "1%s2", str); //Interesting stuff happens here


Not very. What happens on the next line is far more
interesting, if undefined behavior is "interesting" to you.

> printf(str2);


This is equivalent to

printf("1%alfa% %beta% d%100%d %gamma% %delta%2");

.... which is faulty on several counts: Undefined conversion
specifiers ("%a", "% ", "%b", "%100%", "%2"), and specifiers
without values for them to convert ("%g", "%d"). printf()
can do whatever it pleases; Garbage In, Garbage Out.

--
(E-Mail Removed)

 
Reply With Quote
 
 
 
 
Ben Pfaff
Guest
Posts: n/a
 
      03-14-2008
(E-Mail Removed) writes:

> Consider the following code:
>
> char str[100];
> char str2[100];
> strcpy(str, "%alfa% %beta% d%100%d %gamma% %delta%");
> printf("printf: ");
> printf("1%s2", str);
> printf("\nsprintf: ");
> sprintf(str2, "1%s2", str); //Interesting stuff happens here
> printf(str2);


You mean:
printf("%s", str2);
Otherwise the % directives in str2 are interpreted by printf(),
with undefined results.

> printf("\n");


--
char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa6 7f6aaa,0xaa9aa9f6,0x11f6},*p
=b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
2:{i++;if(i)break;else default:continue;if(0)case 1utchar(a[i&15]);break;}}}
 
Reply With Quote
 
Martien Verbruggen
Guest
Posts: n/a
 
      03-14-2008
On Fri, 14 Mar 2008 13:38:21 -0700 (PDT),
(E-Mail Removed) <(E-Mail Removed)> wrote:
> Consider the following code:
>
> char str[100];
> char str2[100];
> strcpy(str, "%alfa% %beta% d%100%d %gamma% %delta%");
> printf("printf: ");
> printf("1%s2", str);
> printf("\nsprintf: ");
> sprintf(str2, "1%s2", str); //Interesting stuff happens here
> printf(str2);


This line is the problem. Not the previous one.

What you're trying to do is

printf("%s", str2);

What you're doing is passing str2 as the format specifier to printf,
which means it will try to parse and interpret it as such, with many
problems and undefined results due to invalid format specifications and
missing parameters.

> Unless I have misunderstand the specification of sprintf there is a
> quite critical bug in sprintf and this in several compilers. Is this
> an known problem? Are more compilers affected? Why are the problem in
> both Visual C++ and GCC? Isn't this very interesting?


It is probably not a good idea to assume that there is a bug in a
compiler or library, especially not if other compilers support its
behaviour, until you are 100% certain that you're right, and those
compilers are wrong. Apart from anything else, it just means that you
waste your time chasing red herrings.

Regards,
Martien
--
|
Martien Verbruggen | The world is complex; sendmail.cf reflects
| this.
|
 
Reply With Quote
 
Martin Ambuhl
Guest
Posts: n/a
 
      03-14-2008
(E-Mail Removed) wrote:
> Consider the following code:


[replaced with the legal program, with one extra line:]
#include <stdio.h>
#include <string.h>

int main(void)
{
char str[100];
char str2[100];
strcpy(str, "%alfa% %beta% d%100%d %gamma% %delta%");
printf("printf: ");
printf("1%s2", str);
printf("\nsprintf: ");
sprintf(str2, "1%s2", str); /* Interesting stuff happens here */
printf(str2);
printf("\n");
printf("%s\n", str2); /* the extra line */
return 0;
}

> The code should format the string "1%s2" by replacing %s with "%alfa%
> %beta% d%100%d %gamma% %delta%". First printf is used, and then
> sprintf. The output should be:
>
> printf: 1%alfa% %beta% d%100%d %gamma% %delta%2
> sprintf: 1%alfa% %beta% d%100%d %gamma% %delta%2


No, it should not. The format string in printf(str2) is
"1%alfa% %beta% d%100%d %gamma% %delta%2"
This format string tells printf to expect several additional arguments:
"%a" (in C99) specifies a double to be represented with
hex digits.
(in C90) undefined conversion
"% " undefined (no space is allowed as a flag in "%%")
"%b" undefined conversion
"% d" signed int represented as decimal integer with a leading space
or '-'
"%100" undefined
"%d" signed int represented as decimal integer
"%g" double represented as with "%f" or "%e"
"% " undefined (no space is allowed as a flag in "%%")
"%d" signed int represented as decimal integer
"%2" undefined (no conversion specified, width = 2)

You provide none of these arguments.
See the result of the added line/


Your various guesses are irrelevant. You call printf with a format
string specifying additional atguments which you do not provide.
 
Reply With Quote
 
Doug Miller
Guest
Posts: n/a
 
      03-15-2008
In article <(E-Mail Removed)>, (E-Mail Removed) wrote:
>Consider the following code:


[crap snipped]

>Unless I have misunderstand the specification of sprintf there is a
>quite critical bug in sprintf and this in several compilers.


Upon sober reflection, which of these circumstances seems to you to be the
more likely of the two?
 
Reply With Quote
 
google@pekspro.com
Guest
Posts: n/a
 
      03-15-2008
On 14 Mar, 21:38, (E-Mail Removed) wrote:
> [A lot of stupid things]


Thanks for all replies that made me feel embarrassed, stupid, and more
embarrassed. To all compilers I just can say:

while(1)
{
printf("I'm sorry!\n");
printf("I will never blame you again.\n");
printf("You make beautiful and prefect things, and I make bugs.\n");
printf("I'm sorry again, please forgive me for my evil words.\n");
printf("You are the master, and I'm the stupid slave.\n\n");
}

I really should know better than this. I will never make any more
premature conclusions (at least not this week).

PEK
 
Reply With Quote
 
Richard Heathfield
Guest
Posts: n/a
 
      03-15-2008
(E-Mail Removed) said:

> On 14 Mar, 21:38, (E-Mail Removed) wrote:
>> [A lot of stupid things]

>
> Thanks for all replies that made me feel embarrassed, stupid, and more
> embarrassed.


Yes, it can be a bit face-reddening, can't it? Generally speaking, The
Compiler Is Always Right. This isn't actually true, but it's a very useful
lie with considerable explanatory power. Of course compilers have bugs -
but the number of bugs in mainstream compilers or standard libraries that
are likely to be first reported by a relatively inexperienced programmer
is vanishingly small.

In general, then, if you and the implementation disagree, you may safely
assume that you are wrong.

War story: when Visual Studio 6 was relatively fresh and exciting, a *very*
inexperienced programmer showed me this program, which he'd copied from
K&R2:

#include <stdio.h>

/* count characters in input: first version */
main()
{
long nc;
nc = 0;
while (getchar() != EOF)
++nc;
printf("%ld\n", nc);
}

He could not get it to produce any output. I smiled, and explained how to
trigger the loop condition with ^Z, and he said that actually he happened
to know about that, and in any case it wouldn't produce any output even
when data was redirected in from a file.

He was convinced that he had somehow mistyped something, and had compared
every single character to the K&R2 original. He'd changed spacing, used
tabs, changed the tab size on his editor - everything. He couldn't see
what he'd done wrong, but he was sure he'd done *something* wrong.

You know where I'm headed with this, I'm sure. The bug was fixed in
Microsoft's next Visual Studio Service Pack.

So yes, inexperienced programmers do sometimes find bugs in
implementations. But it doesn't happen much more often than Patent Office
clerks win Nobel Prizes.

An experienced programmer will assume, in the first instance, that his or
her code is wrong (because, in his or her experience, that is the most
likely explanation). It is only after much head-scratching ("that's
funny"), puzzled discussions with colleagues ("what's wrong with this
code?"), and detailed consultations with experts in the field ("well, /I/
can't see anything wrong with my code, but there must be something wrong
with it - how about it, folks?"), that he or she might eventually conclude
that the compiler or the library implementation is in error.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
printf affects following printf/s azza C Programming 0 10-17-2010 09:43 AM
How to suggest Kernel#printf to add a note to see sprintf Jian Lin Ruby 1 05-05-2010 08:49 PM
Bug in ruby printf/sprintf paul.dlug@gmail.com Ruby 4 07-29-2006 09:40 AM
(void) printf vs printf whatluo C Programming 29 09-08-2005 05:42 PM
bus error with printf line included, error without printf line? ben C Programming 4 06-26-2004 04:42 PM



Advertisments