Solved

itoa function

Posted on 2001-07-31
2,010 Views
I wrote a program in Visual C++ that uses this function to convert an int to a string.  When I moved the code to a UNIX box and compiled there, it failed.  I get the messge: The function "itoa" must have a prototype.

Can anyone tell me why this is happening and how I can get the function to run correctly.

Note, I also use atoi and it didn't say anything about that.
0
Question by:znbg
• 11
• 10
• 2
• +2

LVL 86

Expert Comment

ID: 6338448
'itoa()' should be available from 'stdlib.h'. If you cannot find it there, you can easily 'emulate' that behaviour by writing your own:

/* helper routine that does the main job. */

static void __cdecl xtoa (
unsigned long val,
char *buf,
int is_neg
)
{
char *p;                /* pointer to traverse string */
char *firstdig;         /* pointer to first digit */
char temp;              /* temp char */
unsigned digval;        /* value of digit */

p = buf;

if (is_neg) {
/* negative, so output '-' and negate */
*p++ = '-';
val = (unsigned long)(-(long)val);
}

firstdig = p;           /* save pointer to first digit */

do {
digval = (unsigned) (val % radix);
val /= radix;       /* get next digit */

/* convert to ascii and store */
if (digval > 9)
*p++ = (char) (digval - 10 + 'a');  /* a letter */
else
*p++ = (char) (digval + '0');       /* a digit */
} while (val > 0);

/* We now have the digit of the number in the buffer, but in reverse
order.  Thus we reverse them now. */

*p-- = '\0';            /* terminate string; p points to last digit */

do {
temp = *p;
*p = *firstdig;
*firstdig = temp;   /* swap *p and *firstdig */
--p;
++firstdig;         /* advance to next two digits */
} while (firstdig < p); /* repeat until halfway */
}

/* Actual functions just call conversion helper with neg flag set correctly,
and return pointer to buffer. */

char * __cdecl _itoa (
int val,
char *buf,
)
{
if (radix == 10 && val < 0)
else
xtoa((unsigned long)(unsigned int)val, buf, radix, 0);
return buf;
}
0

LVL 86

Accepted Solution

jkr earned 100 total points
ID: 6338451
BTW: If it's just about converting a number to a string on a decimal basis, you could use

char* itoa10 ( int nValue, char* buf)
{
sprintf ( buf, "%d", nValue);

return ( buf);
}
0

LVL 30

Expert Comment

ID: 6338485
itoa is not part of the ANSI C++ standards.
Some compilers have itoa or _itoa as part of the stdlib.h, but not all compilers support this non-standard function.

I suggest you use one of jkr's above functions to emulate the function.
0

LVL 30

Expert Comment

ID: 6338505
You can also try the following itoa emulated function:

char* itoa(int nValue)
{
static char buffer[64];
sprintf(buffer, "%i", nValue);
return buffer;
}
0

LVL 22

Expert Comment

ID: 6338506
A simpler substitute for itoa() or _itoa() or what ever is

string IntToASCI(int i)
{
stringstream S;

S << i;
return S.str();
}

(This assumes you want base 10.  other bases can be obtained, if necessary).  Tthis is a lot more convenient than itoa() since you do not have to provide a storage space for the resulting string.  it returns a strign object that is automatically sized to the size needed to store the converted value.

0

LVL 30

Expert Comment

ID: 6338705
>>A simpler substitute for itoa() or _itoa() or what ever
>>is

FYI,
This would be a better method if your main concern is the small storage space required by previous posted method.

However, if you're more concern about having a function that works more like the char* itoa() function, nietod's method would not work.

string IntToASCI(int i)
This method would return a string type that would fail in code that requires a pointer to a string.
Example:

int x = 10;
printf("%s",IntToASCI(x));

You can still get nietod's method to work, buy modifying the code to the following:

int x = 10;
printf("%s",IntToASCI(x).c_str());

This would make your code less portable, and it would mean you would have to modify the code where ever this problem presents itself.
If you make the above modifications, the code would not compile when porting it back to it's original platform/compiler.

I recomend using using the function I posted because it will work like the original itoa function.
The small 64-bytes of storage space required for this function is really small and insignificant in MOST target applications.
0

LVL 4

Expert Comment

ID: 6339529
"A simpler substitute for itoa() or _itoa() or what ever is
string IntToASCI(int i)"

Or even:

template<class T>
T StringToType(const string& source)
{
istringstream iss(source);
T ret;
iss >> ret;
return ret;
};

or

template<class T>
T& StringToType(const string& source, T& target)
{
istringstream iss(source);
iss >> target;
return target;
};

and

template<class T>
string ToString(const T& source)
{
ostringstream oss;
oss << source;
return oss.str();
};

===============================================
use them like so:

string s = ToString(123);
int i = StringToType<int>(s);
or
StringToType(s, i);
0

LVL 22

Expert Comment

ID: 6339909
>> This would make your code less portable, and it would
>> mean you would have to modify the code where ever
>> this problem presents itself.
In what way is my suggestion non portable???  It will port to ANY conforming C++ implimentaion.  itoa() and _itoa() certainly won't.

And clearly its not exactlyt he same as itoa((),  it takes different parmeters and returns a different data type.  I pointed it out.

AssafLavie, some very slick templates.  simeple and very effective.
0

LVL 30

Expert Comment

ID: 6340148
>>In what way is my suggestion non portable???  It will
>>port to ANY conforming C++ implimentaion.  itoa()
>>and _itoa() certainly won't.
The code modifications need to use your function is not portable to compilers that include itoa() function with a return type of char*

>>I pointed it out.
Yes, but you did not point out what kind of problems this can cause.
0

LVL 22

Expert Comment

ID: 6341383
>> The code modifications need to use your function
>> is not portable to compilers that include itoa()
>> function with a return type of char*
Yes it is!   it is portable to ALL compilrs.  there's nothing that is non-portable about it.

>> you did not point out what kind of
>> problems this can cause.
its hardly a problem.  The change is trivial and missed changes will always be caught by the compiler.  The lack of support for other bases is a bigger problem.  That can be handled too however.
0

Author Comment

ID: 6341741
That's all I needed!  Thanks!!!!
0

LVL 30

Expert Comment

ID: 6341899
>>The change is trivial and missed changes will always be
>>caught by the compiler.
That's wrong.
Example:
int x = 10;
printf("%s",IntToASCI(x));

The above code does compile, but on run-time, it does not produce the desired results.

It's poor practice to depend on a compiler to catch a poorly written substitute function.
0

LVL 22

Expert Comment

ID: 6341967
>> The above code does compile, but on run-time,
>> it does not produce the desired results.
No kidding!  what does that have to do with portability?

Aren't file stream objects portable?  Well

>> printf("%s",fstream());

compiles and works wrong too!

This has nothing to do with portability.

Obviously if you are going to use a new function in your program, the code is goignt ob e changed.  Its is impossible to keep things exactly the same durign a change.  That is inherient int he definiton of change.   In additioon you can make a change--a change of any type and make it wrong.  That doesn't maen something is non-portable.  non-portable has a very precise meaining.  It means that a non-illformed program cannot be made to compile or to work correctly on all platforms.

>> It's poor practice to depend on a
>> compiler to catch a poorly written
>> substitute function.
There is no gautrantee against people being moronic.  If someone is stupid enough to write code like that they are going to have problems.  At the very least they shouldn't be using pritnf() for reasons I've tried to convince you of, and you never accepted, yet here you showing how bad it is

By the same token you could argue that your code is "non-portable" because

code like

char s1[10];
char s2[10];
_itoa(s1,123);
_itoa(s2,456);

when converted produces

char *s1 = itoa(123);
char *s2 = itoa(345);

because now s1 and s2 both store "345".   That is a problem, it no longer produces the right results  Is that a sign that the code is not portable?  No!  its a sign that someone changed the code to use a new function and didn't do it correctly.  (Its also a sign of a pretty major weakness in the function, one that is nearly impossible to get around under soem circumstances, like multi-threading.)
0

LVL 30

Expert Comment

ID: 6342069
>>No kidding!  what does that have to do with portability?
No kidding!  It's not suppose to have anything to do with portability.
I'm addressing the statement you made that said "missed changes will always be caught by the compiler"

So I don't know why you're trying to bring portability issue into the picture.

The fact is that you're suggesting to depend on a compiler to catch a poorly written substitute function.

>>If someone is stupid enough to write code like
>>that they are going to have problems.
You're the one who's always posting some of the wall poorly written code as an example on how a method can fail to work.
It's seems alright when you right these moronic examples, but not alright when someone else does.
0

LVL 22

Expert Comment

ID: 6342188
>> No kidding!  It's not suppose to have
>> anything to do with portability.

So when you said "This would make your code less portable."  That is your way of saying that it has nothig to do with portability?

>> I don't know why you're trying to bring
>> portability issue into the picture.
Because you said my code was not portable.  I know it is portable. Its obviously portable.  Why are you bring it up?

IS THE CODE PORTABLE?

>> You're the one who's always posting
>> some of the wall poorly written code
>> as an example on how a method
>> can fail to work.
but with reason.  There has to be some expecaction of reasonable resposibility on the programmers part.  Otherwise no techniqyue is safe.  The return value of ANY function can cause printf() to fail.  Does that mean that any technique that would call a fucntion is therefore unsafe?  No, it means that printf() is unsafe.

0

LVL 30

Expert Comment

ID: 6342247
>>So when you said "This would make your code less
>>portable."  That is your way of saying that it has
>>nothig to do with portability?

Is this your way of trying to avoid the subject?
"missed changes will always be caught by the compiler"

If you want to talk about something else, that's find with me, but don't make my last two comments about portability, when it has nothing to do with it.

If you're not going to address the fact that you gave bad advise with "missed changes will always be caught by the compiler", then you need to stop referrencing my last comments because that's the only thing I'm addressing there.
0

LVL 22

Expert Comment

ID: 6342334
>> Is this your way of trying to avoid the subject?
What subject?  you claimed my code is not protable.  Why is it not protable?  Or are you now stating that it is portable?  WHICH IS IT?

>> "missed changes will always be
>> caught by the compiler"
Tht is not a missed change.  The programmer had to go an make the change there.  They changed the code to work in an unsafe manner.

Virtually all ocde can be made unsafe.  You can't criticize something for being unsafe if you have to work hard to make it so!   Your code can be made unsafe.  The original atof() can be made unsafe  (pass a NULL pointer).  You do everything within reason to make code safe, but there are limitations to what can be done.

In addition you are presenting this as if it is somehow related to my code.  its not.  The problem is with printf(0, not my code.  Any code that uses printf is inheriently risky.

>> If you want to talk about something
>> else, that's find with me
You started of talking about portability?  Are you now admiting the code is portable?   Come on!

>> "missed changes will always be
>> caught by the compiler",
Who do you think changed the code so it no longer uses atof()?   Someone had to do that.  Adn at that time they had to examine the code and make changes to make the code work correctly.  That is part of making a change.

>> stop referrencing my last comments
>> because that's the nly

AXTER'S CODE IS FULL OF BUGS AND WILL CRASH IF YOU ATTEMPT TO USE IT.

Your code will require changes whenever it is called, just like mone.

Please confine your responses only to the last thing I said.  (Yeah right!)
0

LVL 30

Expert Comment

ID: 6342436
>>Virtually all ocde can be made unsafe.  You can't
>>criticize something for being unsafe if you have to
>>work hard to make it so!
Wow, that sounds very familiar.  Isn't that the same thing I said when you said crosscasting is unsafe?

Since you don't want to talk about your screw-up, I see no reason why I should have to talk to you about what you want to talk about.
0

LVL 22

Expert Comment

ID: 6342773
Are you just trying to cause trouble.  Or do you really nut understand?  I can't believe anyone couldn't understand?

You do everythign reasonable to avoid problems.  You don't do things that are unreasonable.  You don't do nothing.  You do everythign that is reasonable.

Here you essentially suggestiong that ALL procedure calls be avoided because printf() is unsafe.   That is not reasonable.  But this is what you are suggestiong.  (Avoidning printf() is reasoanble however, why you don't see that is beyond me.)  Actually i know that you are only suggesting that my function call be avoided, but that is stupid, the logic applies to all function calls, and also all expresions too.  You need to avoid those too.  That is not reasonable.  It causes far mroe problems than it avoids.  But what is reasonable?  Not using printf() is reasonable.  It avoids this problem and others.  That is a resonable solution.  On the other question  what is resonable?  Not using dynamic_cast is not resonable.  its a powerful tool and of great help when used correctly.   using dynamic cast indescrimiantely is not reasoanble.  its ganderios when used inappropriately.  it can lead to cude that is unsefe under modications. (modificatiosn that occur in other parts of the code.)  So that is not reasoanble   But usign it in the three methods I discribed that is reasoanble.  You have all the power fo the dymaic_)cast that way.  Yet you have no risk of unexpected behavior.

And what about the portability of my code?  Why is it not portable?  Its not protable because you said it is not portable and just don't want to change your mind about that/  Or do you have some facts you would like to offer?
0

LVL 30

Expert Comment

ID: 6342906
nietod,
Again, since you don't want to talk about your screw-up, I see no reason why I should have to talk to you about
what you want to talk about.
0

LVL 22

Expert Comment

ID: 6344322
What screw up?

You said my code is not portable?  Is my code not portable?
0

LVL 4

Expert Comment

ID: 6344329
0

LVL 30

Expert Comment

ID: 6345506
0

LVL 22

Expert Comment

ID: 6345521
What screw up?  You are making accusations again.  Support them or retract them.

Why is the code not portable?  support that or retract that.
0

LVL 30

Expert Comment

ID: 6345537
nietod,
>>What screw up?  You are making accusations again.
I've repeated myself three times.  If you don't understand by know, then you will never understand.
I'm not repeating myself again.  It's a waste of time with you.
0

LVL 22

Expert Comment

ID: 6345930
What are you babbeling about?  Where is this screw up?

Is the reason you won't "repeat yourself" the fact that you are obviously wrong?
0

Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there isâ€¦
Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [sâ€¦
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.