sprintf function

E

Earth

Hi all,

I am new to c and trying the sprintf function.

I have written a testing program to try the sprintf fuction and expect
the output is 1.234. However, the output shows nothing.

Am I missing sth here?

Thanks in advance for you inputs.

Earth

#include <stdio.h>
char* toString(double d)
{
char buffer[9];
sprintf(buffer, "%lf", d);
return buffer;
}

main()
{
printf("%s\n", toString(1.234));
}
 
M

Morris Dovey

Earth said:
#include <stdio.h>
char* toString(double d)
{
char buffer[9];
sprintf(buffer, "%lf", d);
return buffer;
}

main()
{
printf("%s\n", toString(1.234));
}

What do you suppose happens to buffer[9] when you return from
toString()?

(BTW toString is not a valid identifier)
 
N

nrk

Earth said:
Hi all,

I am new to c and trying the sprintf function.

I have written a testing program to try the sprintf fuction and expect
the output is 1.234. However, the output shows nothing.

Am I missing sth here?

Thanks in advance for you inputs.

Earth

#include <stdio.h>
char* toString(double d)
{
char buffer[9];
sprintf(buffer, "%lf", d);
return buffer;
}

main()
{
printf("%s\n", toString(1.234));
}

Congratulations!! You hit the FAQ jackpot. In fact, we even have an FAQ
that actually uses sprintf while answering your very question. You can
find this question and answer at:

http://www.eskimo.com/~scs/C-faq/q7.5.html

Please to take the time to go through the fine FAQ. It's available at:

http://www.eskimo.com/~scs/C-faq/top.html

-nrk.
 
T

Tom St Denis

Peter Pichler said:

Can't start with "to". It's reserved for things like tolower, toupper,
etc...

Technically it's not "buggy C" just not portable. Just like using "errno"
for a local variable isn't a great idea neither.

Tom
 
P

Peter Pichler

Tom St Denis said:
Can't start with "to".

....and a lowercase letter.
It's reserved for things like tolower, toupper,
etc...

But not toString. 'S' is not a lowercase letter, AFAICS.
Technically it's not "buggy C" just not portable. Just like using "errno"
for a local variable isn't a great idea neither.

Not only is it portable, it is also recommended. Either that or is_string().

Peter
 
E

Eric Amick

I am new to c and trying the sprintf function.

I have written a testing program to try the sprintf fuction and expect
the output is 1.234. However, the output shows nothing.

Am I missing sth here?

#include <stdio.h>
char* toString(double d)
{
char buffer[9];
sprintf(buffer, "%lf", d);
return buffer;
}

I see several problems:

1. %lf is not a valid specifier for sprintf; you want %f, which works
for both float and double types. Many implementations will let you get
away with this, but you should get in the habit of using the right one.

2. The buffer allows for only 8 characters in the representation of the
number. If the number has more digits than that, things could get ugly.

3. You're returning a pointer to a buffer that goes away when the
function returns, which will have unpredictable consequences. The
program could just as well have aborted. This is the one that is the
immediate issue.

There are several solutions to this last problem. One is to declare
buffer as static char so that it remains after the function exits;
another is to use the malloc() function to allocate the memory instead
and return a pointer to that memory; yet another is to allocate the
buffer in the main program and pass a pointer to that buffer to the
function and store the result there. Any of these will work for toy
programs, but the last two are generally better choices for real code.
 
N

nrk

Tom said:
Can't start with "to". It's reserved for things like tolower, toupper,
etc...

Tom, you might want to think twice before giving an "obvious" answer when
one respected clc regular is questioning another respected clc regular.
IMHO, such threads and sub-threads must be marked clearly in bold red type:
"Here be dragons" :)

-nrk.
 
T

Tom St Denis

nrk said:
Tom, you might want to think twice before giving an "obvious" answer when
one respected clc regular is questioning another respected clc regular.
IMHO, such threads and sub-threads must be marked clearly in bold red type:
"Here be dragons" :)

True dat. I'll bow out of this conversation. Though I'll add my two cents.
Generally it isn't a good idea to start functions without a descriptive
name. e.g. mp_*() for multiple precision math, etc...

Tom
 
P

Peter Pichler

nrk said:
Tom, you might want to think twice before giving an "obvious" answer when
one respected clc regular is questioning another respected clc regular.

*blush*

When did I become a respected clc regular? I thought that one needs to be
marked as an "obvious troll" by ERT first... ;-)

Peter
 
J

Jack Klein

Earth said:
#include <stdio.h>
char* toString(double d)
{
char buffer[9];
sprintf(buffer, "%lf", d);
return buffer;
}

main()
{
printf("%s\n", toString(1.234));
}

What do you suppose happens to buffer[9] when you return from
toString()?

(BTW toString is not a valid identifier)

Actually toString is a valid identifier. The standard says:

"7.26.2 Character handling <ctype.h>
1 Function names that begin with either is or to, and a lowercase
letter may be added to the declarations in the <ctype.h> header."

Identifiers beginning with "is" or "to" followed by an underscore,
digit, or uppercase letter do not violate the reserved name space.
 
M

Martin Ambuhl

Earth wrote:
....
I have written a testing program to try the sprintf fuction and expect
the output is 1.234. However, the output shows nothing. ....
#include <stdio.h>
char* toString(double d)
{
char buffer[9];
sprintf(buffer, "%lf", d);
return buffer;
}

main()
{
printf("%s\n", toString(1.234));
}

But this code ...

#include <stdio.h>
char *toString(double d)
{
static char buffer[9];
sprintf(buffer, "%lf", d);
return buffer;
}

int main(void)
{
printf("%s\n", toString(1.234));
return 0;
}

Has this output:
1.234000

Notice the difference?
 
M

Martin Ambuhl

Peter said:

It is a valid identifier. But 'tostring' (with external linkage),
beginning with 'to' followed by a lowercase letter would be a name reserved
to the implementation no matter what headers are included.
 
M

Mark McIntyre

But not toString. 'S' is not a lowercase letter, AFAICS.

This is certainly true in US Ascii but I'd be interested to know if
its absolutely guaranteed in every possible locale.
My own opinion is that its safest just to avoid to... is... and str...
identifiers entirely.
 
J

Josh Sebastian

This is certainly true in US Ascii but I'd be interested to know if
its absolutely guaranteed in every possible locale.

Doesn't matter: 5.2.1#3 specifies which characters are "uppercase" and
which are "lowercase" in the source character set.

Josh
 
P

Peter Nilsson

Jack Klein said:
Earth said:
#include <stdio.h>
char* toString(double d)
{
char buffer[9];
sprintf(buffer, "%lf", d);
return buffer;
}

main()
{
printf("%s\n", toString(1.234));
}

What do you suppose happens to buffer[9] when you return from
toString()?

(BTW toString is not a valid identifier)

Actually toString is a valid identifier. The standard says:

"7.26.2 Character handling <ctype.h>
1 Function names that begin with either is or to, and a lowercase
letter may be added to the declarations in the <ctype.h> header."

Identifiers beginning with "is" or "to" followed by an underscore,
digit, or uppercase letter do not violate the reserved name space.

Although, case insensitivity of external identifiers is implementation
defined in C90. [This was deprecated and indeed removed in C99.]
 
J

Jack Klein

Jack Klein said:
Earth wrote:

#include <stdio.h>
char* toString(double d)
{
char buffer[9];
sprintf(buffer, "%lf", d);
return buffer;
}

main()
{
printf("%s\n", toString(1.234));
}

What do you suppose happens to buffer[9] when you return from
toString()?

(BTW toString is not a valid identifier)

Actually toString is a valid identifier. The standard says:

"7.26.2 Character handling <ctype.h>
1 Function names that begin with either is or to, and a lowercase
letter may be added to the declarations in the <ctype.h> header."

Identifiers beginning with "is" or "to" followed by an underscore,
digit, or uppercase letter do not violate the reserved name space.

Although, case insensitivity of external identifiers is implementation
defined in C90. [This was deprecated and indeed removed in C99.]

Immaterial, the patterns that are and are not reserved by this clause
were identical in C90, although the wording was a little different:

"7.13.2 Character handling <ctype.h>
Function names that begin with either is or to, and a lowercase letter
(followed by any combination of digits, letters, and underscore) may
be added to the declarations in the <ctype.h> header."
 
P

Peter Nilsson

Jack Klein said:
Jack Klein said:
Earth wrote:

#include <stdio.h>
char* toString(double d)
{
char buffer[9];
sprintf(buffer, "%lf", d);
return buffer;
}

main()
{
printf("%s\n", toString(1.234));
}

(BTW toString is not a valid identifier)

Actually toString is a valid identifier. The standard says:

"7.26.2 Character handling <ctype.h>
1 Function names that begin with either is or to, and a lowercase
letter may be added to the declarations in the <ctype.h> header."

Identifiers beginning with "is" or "to" followed by an underscore,
digit, or uppercase letter do not violate the reserved name space.

Although, case insensitivity of external identifiers is implementation
defined in C90. [This was deprecated and indeed removed in C99.]

Immaterial, the patterns that are and are not reserved by this clause
were identical in C90...

C90 _implicitly_ reserves a broader range of external identifiers for
implementations which do not have case sensitive external linkage.

I don't have C90 itself (only a draft), but I have seen numerous posts
quoting ANSI 4.1.2.1

All identifiers with external linkage in any of the following sections
(including the future library directions) are always reserved for use
as identifiers with external linkage.

So, if tostri* is reserved as an external identifier in C90 (as it is), then
using toStri* as an external identifier will preclude strict conformance.
It's undefined behaviour on machines with case insensitive external
linkage.[*]

If 'Earth' had declared toString static, there wouldn't be a problem.

[*] I don't know of any conforming implementations having this _feature_
exist, but nonetheless, C90 allows for them.
 
I

Irrwahn Grausewitz

Peter Pichler said:
"nrk" <[email protected]> wrote:

*blush*

When did I become a respected clc regular? I thought that one needs to be
marked as an "obvious troll" by ERT first... ;-)

That seems to be a necessary, albeit not sufficient, prerequisite
when applying for regular status in c.l.c. ;-)

Regards
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top