943,884 Members | Top Members by Rank

Ad:
  • C++ Discussion Thread
  • Marked Solved
  • Views: 4315
  • C++ RSS
You are currently viewing page 1 of this multi-page discussion thread
Apr 24th, 2009
0

Trying to write itoa

Expand 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.
c++ Syntax (Toggle Plain Text)
  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:
c++ Syntax (Toggle Plain Text)
  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!
Similar Threads
Reputation Points: 10
Solved Threads: 0
Newbie Poster
AnujSuper9 is offline Offline
15 posts
since Apr 2009
Apr 24th, 2009
0

Re: Trying to write itoa

I wrote something equal using strings, look at this snippet so you can see how it' done ...

Hope this helps !
Reputation Points: 2125
Solved Threads: 243
Postaholic
tux4life is offline Offline
2,105 posts
since Feb 2009
Apr 24th, 2009
1

Re: Trying to write itoa

Click to Expand / Collapse  Quote originally posted by AnujSuper9 ...
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)
C++ Syntax (Toggle Plain Text)
  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)
C++ Syntax (Toggle Plain Text)
  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.
Moderator
Reputation Points: 3278
Solved Threads: 892
Posting Sage
WaltP is offline Offline
7,718 posts
since May 2006
Apr 24th, 2009
0

Re: Trying to write itoa

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.
Reputation Points: 1268
Solved Threads: 228
Posting Virtuoso
vmanes is offline Offline
1,895 posts
since Aug 2007
Apr 24th, 2009
0

Re: Trying to write itoa

Hmmm, ok. Let me make some adjustments.

c++ Syntax (Toggle Plain Text)
  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.

--
Quote ...
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?

Quote ...
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.
Reputation Points: 10
Solved Threads: 0
Newbie Poster
AnujSuper9 is offline Offline
15 posts
since Apr 2009
Apr 24th, 2009
0

Re: Trying to write itoa

So I updated my current implementation in the last post. Does anyone else have any suggestions for me?
Reputation Points: 10
Solved Threads: 0
Newbie Poster
AnujSuper9 is offline Offline
15 posts
since Apr 2009
Apr 24th, 2009
0

Re: Trying to write itoa

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.
Reputation Points: 1268
Solved Threads: 228
Posting Virtuoso
vmanes is offline Offline
1,895 posts
since Aug 2007
Apr 24th, 2009
0

Re: Trying to write itoa

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:
C++ Syntax (Toggle Plain Text)
  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.
Reputation Points: 352
Solved Threads: 109
Master Poster
skatamatic is online now Online
779 posts
since Nov 2007
Apr 24th, 2009
0

Re: Trying to write itoa

Ok, here is my current implementation:

c++ Syntax (Toggle Plain Text)
  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.
Reputation Points: 10
Solved Threads: 0
Newbie Poster
AnujSuper9 is offline Offline
15 posts
since Apr 2009
Apr 25th, 2009
0

Re: Trying to write itoa

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!
Reputation Points: 1268
Solved Threads: 228
Posting Virtuoso
vmanes is offline Offline
1,895 posts
since Aug 2007

This thread is solved

Either the thread starter or a moderator has marked this thread as solved. You can most likely trust the responses and answers given. There is most likely no reason for any further responses to be posted here. If you have a related question, please start a new thread in this forum instead.

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in C++ Forum Timeline: C++ newbie, Need help solving a problem for class
Next Thread in C++ Forum Timeline: writing certain values from a file





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC