|
|
|
#1 |
|
Messages: n/a
Hébergeur: |
Here is my 1st attempt at the solution for K&R2 Exercise 4-12:
void itoa(int n, char *s) { if (n < 0) { *s++ = '-'; n = -n; } if( n/10 > 0 ) itoa( n/10, s ); *s++ = n%10 + '0'; *s = 0; } I realize why my code is not working, it's because the increments don't carry forward when the recursive calls "unwind." I can solve this this way: void itoa2(int n, char *s) { static char *p = 0; if(p == 0) p = s; if (n < 0) { *p++ = '-'; n = -n; } if( n/10 > 0 ) itoa2( n/10, p ); *p++ = n%10 + '0'; *p = 0; } This keeps the p pointer up-to-date while the recursive calls unwind. My quesiton is, does anyone know of a solution that doesn't require the introduction of a static duration variable? Something like a small modifcation to my first attempt? |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
Lax said:
> Here is my 1st attempt at the solution for K&R2 Exercise 4-12: > > void itoa(int n, char *s) > { > > if (n < 0) > { > *s++ = '-'; > n = -n; > } > > if( n/10 > 0 ) > itoa( n/10, s ); > > *s++ = n%10 + '0'; > *s = 0; > } > > > I realize why my code is not working, it's because the increments > don't carry forward when the recursive calls "unwind." In a real itoa, you'd want to take a maximum length, to reduce the risk of buffer overruns. The following fixes your problem, I think (although I haven't actually tested it). void itoasub(int n, char **s) { if(n / 10 > 0) { itoasub(n / 10, s); } **s = n % 10 + '0'; ++*s; } void itoa(int n, char *s) { if(n < 0) { *s++ = '-'; n = -n; /* beware INT_MIN! */ } itoasub(n, &s); *s = 0; } -- Richard Heathfield <http://www.cpax.org.uk> Email: -http://www. +rjh@ Google users: <http://www.cpax.org.uk/prg/writings/googly.php> "Usenet is a strange place" - dmr 29 July 1999 |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
"Lax" <Lax.Clarke@gmail.com> wrote in message news:1737a679-a647-40be-a053-47a96987c45b@k37g2000hsf.googlegroups.com... > Here is my 1st attempt at the solution for K&R2 Exercise 4-12: > > void itoa(int n, char *s) > { > > if (n < 0) > { > *s++ = '-'; > n = -n; > } > > if( n/10 > 0 ) > itoa( n/10, s ); > > *s++ = n%10 + '0'; > *s = 0; > } Try this; it uses a local variable, and calls strlen a lot, so is a bit slower: void itoa(int n, char *s) {int len; *s=0; if (n < 0) { *s++ = '-'; n = -n; } if( n>=10 ) itoa( n/10, s ); len=strlen(s); s[len]= n%10 + '0'; s[len+1]=0; } -- Bart |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
Lax <Lax.Clarke@gmail.com> writes:
> Here is my 1st attempt at the solution for K&R2 Exercise 4-12: <snip not quite solution> > I can solve this this way: > > void itoa2(int n, char *s) > { > static char *p = 0; > > if(p == 0) > p = s; > > if (n < 0) > { > *p++ = '-'; > n = -n; Small point: in C -n can overflow. I am sure that K&R don't intend that you deal with this here, but a real itoa would have to. > } > > if( n/10 > 0 ) > itoa2( n/10, p ); > > *p++ = n%10 + '0'; > *p = 0; > } > > > This keeps the p pointer up-to-date while the recursive calls unwind. > > My quesiton is, does anyone know of a solution that doesn't require > the introduction of a static duration variable? Something like a small > modifcation to my first attempt? Well, not a tweak but a general idea: recursion works particularly well with functions that have simple value parameters and return useful results. In fact, that pattern can be grown into a whole methodology of programming. Since the interface of itoa is fixed, you need a er function. The trick is thinking up the most ful function you can imagine. Often that function can then be written in terms of itself and the desired function becomes a simple call of it with a little extra house-keeping. For example: Given 'char *aux_itoa(int n, char *s);' that takes a positive 'n', puts the character representation of 'n' into 's' and returns a pointer to the end of that representation, could you write both itoa and also aux_itoa? -- Ben. |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
On Sun, 13 Apr 2008 08:14:18 +0100, Lax <Lax.Clarke@gmail.com> wrote:
> Here is my 1st attempt at the solution for K&R2 Exercise 4-12: > > void itoa(int n, char *s) > { > > if (n < 0) > { > *s++ = '-'; > n = -n; > } > > if( n/10 > 0 ) > itoa( n/10, s ); > > *s++ = n%10 + '0'; > *s = 0; > } Any comments on Tondo & Gimpel's solution, in THE C ANSWER BOOK? #include <math.h> /* itoa: convert n to characters in s; recursive */ void itoa(int n, char s[]) { static int i; if ( n / 10 ) itoa(n / 10, s); else { i = 0; if (n < 0) s[i++] = '-'; } s[i++] = abs(n) % 10 + '0'; s[i] = '0'; } -- Martin |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
Martin wrote, On 15/04/08 13:44:
<snip> > Any comments on Tondo & Gimpel's solution, in THE C ANSWER BOOK? If you have correctly presented it, then it is not very good. > #include <math.h> This header is not needed. > /* itoa: convert n to characters in s; recursive */ > void itoa(int n, char s[]) > { > static int i; > > if ( n / 10 ) > itoa(n / 10, s); > else { > i = 0; > if (n < 0) > s[i++] = '-'; > } > s[i++] = abs(n) % 10 + '0'; For abs you should include stdlib.h > s[i] = '0'; > } Now try running it with the following main function calling it... int main(void) { char s1[]="abcdef",s2[]="ghijk"; itoa(1,s1); itoa(2,s2); printf("1='%s' 2='%s'\n",s1,s2); return 0; } Then try reading the code and see if you can find the error. -- Flash Gordon |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
"Flash Gordon" <spam@flash-gordon.me.uk> wrote in message
news e7fd5xqel.ln2@news.flash-gordon.me.uk...> Martin wrote, On 15/04/08 13:44: > > <snip> > >> Any comments on Tondo & Gimpel's solution, in THE C ANSWER BOOK? > > If you have correctly presented it, then it is not very good. > >> #include <math.h> > > This header is not needed. > >> /* itoa: convert n to characters in s; recursive */ >> void itoa(int n, char s[]) >> { >> static int i; >> >> if ( n / 10 ) >> itoa(n / 10, s); >> else { >> i = 0; >> if (n < 0) >> s[i++] = '-'; >> } >> s[i++] = abs(n) % 10 + '0'; > > For abs you should include stdlib.h > >> s[i] = '0'; >> } > > Now try running it with the following main function calling it... > > int main(void) > { > char s1[]="abcdef",s2[]="ghijk"; > itoa(1,s1); > itoa(2,s2); > printf("1='%s' 2='%s'\n",s1,s2); > return 0; > } > > Then try reading the code and see if you can find the error. It has to be a typo (obviously). But even after the obvious fix, there is still a problem with INT_MIN: #include <stdlib.h> /* my_itoa: convert n to characters in s; recursive */ void my_itoa(int n, char s[]) { static int i; if (n / 10) my_itoa(n / 10, s); else { i = 0; if (n < 0) s[i++] = '-'; } s[i++] = abs(n) % 10 + '0'; s[i] = 0; } #include <stdio.h> #include <string.h> #include <limits.h> int main(void) { char s1[80] = "abcdef"; char s2[80] = "abcdef"; my_itoa(INT_MAX, s1); my_itoa(INT_MIN, s2); printf("INT_MAX='%s' INT_MIN='%s'\n", s1, s2); return 0; } ** Posted from http://www.teranews.com ** |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
Lax wrote:
> Here is my 1st attempt at the solution for K&R2 Exercise 4-12: > > void itoa(int n, char *s) <snip> > My quesiton is, does anyone know of a solution that doesn't require > the introduction of a static duration variable? Something like a small > modifcation to my first attempt? Google comp.lang.c for itoa. This is not the first time the function has been discussed. -- Peter |
|
![]() |
| Outils de la discussion | |
|
|