And for strtod's inverse :
double value = ...;
sprintf(buf + strlen(buf), "%lf", value);
of course :)
Main Topics
Browse All TopicsI am coding on Linux, and want to parse text to numbers, and back.
In posix, there are excellent routines like:
double strtod(const char*nptr, char** endptr)
and strtof, strtold, etc.
These routines not only parse, but return a pointer to the position beyond which they've munched, thus giving a fast conversion with a decent way to tell if there was a failure, at the same time as being able to immediately tell where to parse next.
The question is, what is the equivalent routine in the opposite direction? sprintf is slower than it needs to be because of the parsing of the formatting directives, but worse, it doesn't update a pointer showing the position of the end of the print. In certain cases, specifying a width would tell me where the end should be:
sprintf(buf, "%5d", 34)
but that is no guarantee if the number exceeds the field width, so what I really need is the equivalent, low level routine that is the opposite of strtod, etc. assuming one exists.
Thanks,
Dave
This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.
Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.
If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.
Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.
Access the answers to your technology questions today.
30-day free trial. Register in 60 seconds.
Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Try it out and discover for yourself.
30-day free trial. Register in 60 seconds.
Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.
infinity08, your solution does what he explicitly said not to do, ie scan multiple times through the data using sprintf. You first find the length of the buffer (one scan), then parse out the format specifier. Next time, you would have to do it again.
I looked, and though I can see libc.a has itoa etc. for djgpp, it does not compile under linux, and the routines are listed as not being posix. This is rather strange. Can anyone comment?
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char* argv[]) {
int x = 5;
char buffer[256];
printf("%d\n", itoa(x, buffer, 10));
}
And in addition to these integer conversion routines, there's 'gcvt()', 'fcvt()' a´nd 'ecvt()' for floating point data (http://www.icewalkers.com
>> Can anyone comment?
As I said : they are not standard functions (not ANSI C and not POSIX). They are non-standard extensions that are supported by some compilers.
>> infinity08, your solution does what he explicitly said not to do, ie scan multiple times through the data using sprintf.
No, his biggest problem with sprintf() was that it didn't keep track of the position ... that is solved by what I proposed.
His second-biggest problem with sprintf was that the format string needs to be parsed ... that's still the case with my solution obviously, and that's why I asked if that was acceptable.
The alternative is to write the function yourself, so I'd argue that my solution is the simplest way of doing what he wants to do, and on top of that it's portable.
drunnels, what do you think ?
A C++ solution is to use stringstream:
#include <sstream>
#include <iomanip>
using namespace std;
i = 5;
ostringstream oss;
oss << i;
cout << oss.str() << endl;
oss.str() is a std::string. If you need a char buffer you could get it by
char buf[32];
strcpy(buf, oss.str().c_str());
You also could make formatting like
// right justified 5 digits padded up with zeros
oss << setw(5) << right << setfill('0') << i;
The reverse is safe and easier than strtod, strtol.
istringstream iss("12345.12ABC");
double d;
iss >> d;
if (iss.fail())
cout << "12345.12ABC" << " is not a number. " << endl;
Regards, Alex
check out %n format specifier: http://www.cplusplus.com/r
you can get rid of strlen() proposed by inifinity08.
other than that, you can use c++ code already mentioned.
Here is a safe integer to string conversion without any runtime call:
int itostr(int i, char sz[], int sizsz)
{
char c = '0';
int isig = (i == 0)? 0 : (i > 0)? 1 : -1;
char szt[32] = { '\0' };
char* psz = sz;
int siz = 0;
int l = 31;
i *= isig;
while (i > 0)
{
szt[--l] = (char)(i%10 + '0');
i /= 10;
}
if (isig < 0)
szt[--l] = '-';
else if (isig == 0)
szt[--l] = '0';
siz = 32 -l;
if (sizsz >= siz)
{
while (*psz++ = szt[l++]);
return siz;
}
return -siz;
}
The functions returns the needed size of the output string including zero terminator. If the buffer passed is too small it returns the needed size as a negative value. Converting doubles could be made by using a int64 equivalent to the function above and moving the double into integer range. All safe and without any runtime function call and within the maximum precision of a double (about 15 significant digits).
Regards, Alex
Linux (i.e.glibc) sprintf returns the number of bytes output (not including trailing NUL). (BSD doesn't - it returns buffer address). If you need to constrain the output to avoid buffer overflow, use snprintf, which also guarantees to fit in a trailing NUL (which simpler functions like strncpy() don't). Not all implementations of snprintf() are that smart - so far I have only encountered Windows libraries that aren't.
Yes, the freeBSD man page does say printf returns # bytes. The "char *printf()" I tangled with must have been on a pre-ANSII system - I found this entry in the RCS log:
revision 1.3
date: 1995/03/05 10:28:37; author: dunc; state: Exp; lines: +12 -5
Don't rely on integer return from sprintf (BSD returns buf addr)
too bad I didn't log what the system was :(AIX, HP-UX &c.)
Business Accounts
Answer for Membership
by: Infinity08Posted on 2007-05-09 at 08:36:04ID: 19057853
I assume you're talking about C, and not C++ ?
In the standard C libraries, there's no (exact) inverse of strtod. So, it'll have to be something less "straightforward".
Is something like this acceptable to you :
sprintf(buf + strlen(buf), "%5d", 34);
It adds the integer to the end of the string. That should do what you want, unless I'm missing something : it keeps track of the current position (the end of the string), and adds the next data there ...