Trying to write itoa

Please support our C++ advertiser: Intel Parallel Studio Home
Thread Solved

Join Date: Apr 2009
Posts: 15
Reputation: AnujSuper9 is an unknown quantity at this point 
Solved Threads: 0
AnujSuper9 AnujSuper9 is offline Offline
Newbie Poster

Trying to write itoa

 
0
  #1
Apr 24th, 2009
Hello everyone, I'm working on a small assignment where I am supposed to write the code for the itoa function

char* itoa(int Value, int Base);
without using any built-in functions, and where the returned value is allocated on behalf of the caller. Value being the integer to convert, and base being octal, decimal, or hex.

I found this rather simple implementation and I was hoping we could discuss it here to see if the changes I'm making are appropriate/accurate and etc.
  1. char* itoa(int val, int base){
  2. static char buf[32] = {0};
  3. int i = 30;
  4. for(; val && i ; --i, val /= base)
  5. buf[i] = "0123456789abcdef"[val % base];
  6. return &buf[i+1];
  7. }
Here's my current, pseudo-codey implementation:
  1. char* itoa(int val, int base){
  2.  
  3. static char buf[36] = {0};
  4. buf = (char *) malloc(//...);
  5.  
  6. if (val == 0)
  7. return &buf=0;
  8.  
  9. //since base can only be octal, decimal or hex
  10. if (base != 8 || base != 10 || base != 16)
  11. printf("Not a valid base.");
  12.  
  13. for(int i=30; val && i; --i)
  14. {
  15. val /= base;
  16. buf[i] = "0123456789abcdef"[val % base];
  17. }
  18.  
  19. if(value < 0 && base == 10)
  20. //make the output negative
  21.  
  22. return &buf[i+1];
  23. }
Thanks in advance!
Reply With Quote Quick reply to this message  
Join Date: Feb 2009
Posts: 1,968
Reputation: tux4life has a reputation beyond repute tux4life has a reputation beyond repute tux4life has a reputation beyond repute tux4life has a reputation beyond repute tux4life has a reputation beyond repute tux4life has a reputation beyond repute tux4life has a reputation beyond repute tux4life has a reputation beyond repute tux4life has a reputation beyond repute tux4life has a reputation beyond repute tux4life has a reputation beyond repute 
Solved Threads: 214
tux4life's Avatar
tux4life tux4life is offline Offline
Posting Virtuoso

Re: Trying to write itoa

 
0
  #2
Apr 24th, 2009
I wrote something equal using strings, look at this snippet so you can see how it' done ...

Hope this helps !
"Never argue with idiots, they just drag you down to their level and then beat you with experience."
Reply With Quote Quick reply to this message  
Join Date: May 2006
Posts: 3,114
Reputation: WaltP has much to be proud of WaltP has much to be proud of WaltP has much to be proud of WaltP has much to be proud of WaltP has much to be proud of WaltP has much to be proud of WaltP has much to be proud of WaltP has much to be proud of WaltP has much to be proud of 
Solved Threads: 281
Moderator
WaltP's Avatar
WaltP WaltP is offline Offline
Posting Sensei

Re: Trying to write itoa

 
1
  #3
Apr 24th, 2009
Originally Posted by AnujSuper9 View Post
Hello everyone, I'm working on a small assignment where I am supposed to write the code for the itoa function

char* itoa(int Value, int Base);
without using any built-in functions, and where the returned value is allocated on behalf of the caller. Value being the integer to convert, and base being octal, decimal, or hex.

I found this rather simple implementation and I was hoping we could discuss it here to see if the changes I'm making are appropriate/accurate and etc.
OK, have a seat...
1) malloc() -- this will cause memory leaks on each call. Once the function returns, the memory address allocated is lost and can not be returned to the heap. Stick with the static char from the original code.

2)
  1. for(int i=30; val && i; --i)
  2. {
  3. val /= base;
  4. buf[i] = "0123456789abcdef"[val % base];
  5. }
The first thing you do in the loop is remove the low order digit so if you pass in 2765 you would get back 276.

3)
  1. buf[i] = "0123456789abcdef"[val % base];
This is a trick that I personally would avoid -- but that's just me. Create a char* with the character values.
Also, what happens if the base passed in is > 16? This line will cause a lot of trouble. You need to test for proper base range to protect the program this function is used it.
The 3 Laws of the Procrastination Society:
1) Never do today that which can be put off until tomorrow
2) Tomorrow never comes
Reply With Quote Quick reply to this message  
Join Date: Aug 2007
Posts: 1,675
Reputation: vmanes is a splendid one to behold vmanes is a splendid one to behold vmanes is a splendid one to behold vmanes is a splendid one to behold vmanes is a splendid one to behold vmanes is a splendid one to behold vmanes is a splendid one to behold 
Solved Threads: 193
vmanes's Avatar
vmanes vmanes is offline Offline
Posting Virtuoso

Re: Trying to write itoa

 
0
  #4
Apr 24th, 2009
Lines 3 & 4 - you create the array buf, then again allocate memory to it? Why using malloc() when you can use the C++ new? You're on the right track, as to return the string you need to allocate with new so the memory exists outside the function's stack allocation. Declare buf as a char*.

Lines 6 & 7 - you probably don't need to worry about special case of 0, just let the code set a 0 in the output string, as it would any other value. Otherwise, if you want to do this, you'll need to put the char '0' into the string, not in the way your line 7 does.

Line 10 - check the logic of the boolean operator you're using. Will that really reject anything other than 8, 10, 16?

Line 16 - clever. I'd never seen that done or considered it.

Watch your index usage. You start out with array of 36 elements, your processing loop starts at index 30. Pick a size! Remember that last valid index is size-1, and that position better contain a NULL terminator for the string.

I do find it a bit problematic that you will return the address of a point inside the block of memory allocated, thus orphaning the memory at the beginning of that block.
"We Americans got so tired of being thought of as dumb by the rest of the world that we went to the polls last November and removed all doubt."
~~~~~~~~~~~~~~~~~~
Looking for an exciting graduate degree? Robotics and Intelligent Autonomous Systems (RIAS) at SDSM&T See the program brochure here.
Reply With Quote Quick reply to this message  
Join Date: Apr 2009
Posts: 15
Reputation: AnujSuper9 is an unknown quantity at this point 
Solved Threads: 0
AnujSuper9 AnujSuper9 is offline Offline
Newbie Poster

Re: Trying to write itoa

 
0
  #5
Apr 24th, 2009
Hmmm, ok. Let me make some adjustments.

  1. char* itoa(int val, int base)
  2. {
  3. new static char* buf[32] = {0}; //1
  4.  
  5. //since base can only be octal, decimal or hex
  6. if (base != 8 && base != 10 && base != 16) //2
  7. printf("Not a valid base.");
  8.  
  9. for(int i=30; val && i; --i)
  10. {
  11. val /= base;
  12. buf[i] = "0123456789abcdef"[val % base]; //3
  13. }
  14.  
  15. if(value == 0)
  16. //return char 0 //4
  17.  
  18. if(value < 0 && base == 10)
  19. //make the output negative //5
  20.  
  21. return &buf[i+1];
  22. }

1. So 'new' here will work? This will allocate the return value on behalf of the caller?
I was worried that if two consecutive itoa() calls were made, and then they were both output, that the first one would be overridden.

2. LOL, duh, stupid mistake. Thanks vmanes.

3. And actually, could someone please explain
buf[i] = "0123456789abcdef"[val % base]; to me. I found the trick somewhere else, and kind of understand how it works, but I don't exactly understand HOW it works, if you know what I mean.
WaltP, why would you avoid this trick?

4. With the code the way it is, wouldn't I need a special case to account for a value of 0? Otherwise it won't even run the for loop. Additionally, how should a return a char 0?

5. I'm not sure how to make the output negative here exactly.

--
Watch your index usage. You start out with array of 36 elements, your processing loop starts at index 30. Pick a size! Remember that last valid index is size-1, and that position better contain a NULL terminator for the string.
I changed the array of elements to be 32. This should solve both issues, right?

I do find it a bit problematic that you will return the address of a point inside the block of memory allocated, thus orphaning the memory at the beginning of that block.
How would I go about correcting these issues? I'd really like this implementation to be functional as well as optimally efficient.

---
I was getting frustrated with this implementation I was trying above, so I started working on something much much more basic, and therefore probably a lot less efficient, and no doubt soon to be full of problems as well, but seeing your guys' posts here makes me want to make sure this implementation works moreso than the new one I was going to get at. So please bare with me as I try to get the final function for my code.
Last edited by AnujSuper9; Apr 24th, 2009 at 4:03 am.
Reply With Quote Quick reply to this message  
Join Date: Apr 2009
Posts: 15
Reputation: AnujSuper9 is an unknown quantity at this point 
Solved Threads: 0
AnujSuper9 AnujSuper9 is offline Offline
Newbie Poster

Re: Trying to write itoa

 
0
  #6
Apr 24th, 2009
So I updated my current implementation in the last post. Does anyone else have any suggestions for me?
Reply With Quote Quick reply to this message  
Join Date: Aug 2007
Posts: 1,675
Reputation: vmanes is a splendid one to behold vmanes is a splendid one to behold vmanes is a splendid one to behold vmanes is a splendid one to behold vmanes is a splendid one to behold vmanes is a splendid one to behold vmanes is a splendid one to behold 
Solved Threads: 193
vmanes's Avatar
vmanes vmanes is offline Offline
Posting Virtuoso

Re: Trying to write itoa

 
0
  #7
Apr 24th, 2009
Compile and see where the several mistakes still exist.

Line 3 - declaring buf that way doesn't work. You'll need to declare a pointer, then allocate memory to it. I'd also set the last element as the string terminator.

You use the variable i which is declared in the loop at line 9 in your return statement - at that point, i is out of scope. Declare your variable outside the loop (at the beginning of the function?)

Swap lines 11 and 12. As they are, input of 234 at base 10 gives output of 023. You want to strip off and store the lower values, then discard them.

Line 15 - how can val (value - watch that you use the same names!) be anything but 0 at this point? Unless you sent in a really large number.

Line 19 - really, what do you have to do to make the string represent a negative number? Oh, you've destroyed the initial input, so you don't know what it was. Perhaps you need a variable to modify, but keep the input parameter untouched.
"We Americans got so tired of being thought of as dumb by the rest of the world that we went to the polls last November and removed all doubt."
~~~~~~~~~~~~~~~~~~
Looking for an exciting graduate degree? Robotics and Intelligent Autonomous Systems (RIAS) at SDSM&T See the program brochure here.
Reply With Quote Quick reply to this message  
Join Date: Nov 2007
Posts: 390
Reputation: skatamatic will become famous soon enough skatamatic will become famous soon enough 
Solved Threads: 39
skatamatic skatamatic is offline Offline
Posting Whiz

Re: Trying to write itoa

 
0
  #8
Apr 24th, 2009
Your function makes little to no sense to me. Just think about injecting test values into it. Say you pass it 5, base 10:

5 / 10 = 0.5 = 0 (int)
"0123456789abcdef"[0 % 10] = '0'
Well damn. It's already broken and didn't even give me my single digit!

Now try 15
15 / 10 = 1.5 = 1(int)
"0123456789abcdef"[1 % 10] = '1' --->promising start...?
1 / 10 = 0
"0123456789abcdef"[0 % 10] = '0' ----> aww crap!

I think you're going to have to find an alternate method.
And to explain "0123456789abcdef"[val % base]
Basically this takes the base, divides it by the value, spits out the remainder and that servers as the index of the output char in the string previous to the index operator - [].
This works great for single digits by itself:
"0123456789abcdef"[5 % 10] = '5'

But then it can be argued...so does just using the single digit:
"0123456789abcdef"[5] = '5'

I understand what the original author is trying to do by dividing by the base each time to shrink the number (ie access each digit) but it just doesn't seem to work! Unless, perhaps, I'm missing something...

As for the negative:
  1. char * itoa(int iNum, int iBase)
  2. {
  3. char* buf = new char[32];
  4. int i = 0;
  5. if (iNum < 0)
  6. buf[i++] = '-';
  7. //...Code...
  8. }
I wouldn't start the for loop at 30 though, i would start it at whatever i is. (either 0 or 1)
Last edited by skatamatic; Apr 24th, 2009 at 9:23 pm.
Reply With Quote Quick reply to this message  
Join Date: Apr 2009
Posts: 15
Reputation: AnujSuper9 is an unknown quantity at this point 
Solved Threads: 0
AnujSuper9 AnujSuper9 is offline Offline
Newbie Poster

Re: Trying to write itoa

 
0
  #9
Apr 24th, 2009
Ok, here is my current implementation:

  1. #include <stdio.h>
  2.  
  3. char* itoa(int value, int base)
  4. {
  5. static char* buf = new (char [32]); //1
  6. buf[31] = '\0';
  7.  
  8. if (base != 8 && base != 10 && base != 16)
  9. printf("Not a valid base.");
  10.  
  11. int valuecopy;
  12. valuecopy = value;
  13.  
  14. if(value == 0)
  15. return buf = '0'; //2, return char 0
  16.  
  17. int i = 30;
  18. for(; valuecopy && i; --i)
  19. {
  20. buf[i] = "0123456789abcdef"[valuecopy % base];
  21. valuecopy /= base;
  22. }
  23.  
  24. if(value < 0 && base == 10)
  25. {
  26. --i;
  27. buf[i] = '-'; //3, make the output negative
  28. }
  29.  
  30. return &buf[i+1];
  31. }

1. Is this right? For the memory allocation of the output.

2. Will this return a char 0? I'm not sure how to write this line.

3. As with 2, will this make the output appear negative? Again, not sure how to write this line.

----
@skatamatic: With the lines switched as per vmanes observation, it should make much more sense. And as for starting at 0 or 1 instead of 30, if I did this, than the resulting string would be reversed, no?
Last edited by AnujSuper9; Apr 24th, 2009 at 9:29 pm.
Reply With Quote Quick reply to this message  
Join Date: Aug 2007
Posts: 1,675
Reputation: vmanes is a splendid one to behold vmanes is a splendid one to behold vmanes is a splendid one to behold vmanes is a splendid one to behold vmanes is a splendid one to behold vmanes is a splendid one to behold vmanes is a splendid one to behold 
Solved Threads: 193
vmanes's Avatar
vmanes vmanes is offline Offline
Posting Virtuoso

Re: Trying to write itoa

 
0
  #10
Apr 25th, 2009
Does it work? Seems to, except for the line 14/15 part. You cannot assign a single character to the array. You want to put a character '0' into the array and then return the address of where that 0 is, similar to your normal return at the end.

Or just put a '0' in the lowest digit position, and let your processing loop overwrite it, if that 's what happens. If input value was 0, be sure to account for the index i.

Experiment!
"We Americans got so tired of being thought of as dumb by the rest of the world that we went to the polls last November and removed all doubt."
~~~~~~~~~~~~~~~~~~
Looking for an exciting graduate degree? Robotics and Intelligent Autonomous Systems (RIAS) at SDSM&T See the program brochure here.
Reply With Quote Quick reply to this message  
Reply

This thread has been marked solved.
Perhaps start a new thread instead?
Message:


Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC