PHWinfo banniere

Titres
PORTAIL ANNUAIRE ARTICLES COMPARATEUR HÉBERGEURS DEVIS FORUMS RÉDUCTEUR D'URL
Précédent   PHWinfo > Autres forums > Forum Programmation & Conception > comp.lang.c > K&R2 Exercise 4-12
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
K&R2 Exercise 4-12

Réponse
 
LinkBack Outils de la discussion
Vieux 13/04/2008, 08h14   #1
Lax
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut K&R2 Exercise 4-12

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?
  Réponse avec citation
Vieux 13/04/2008, 08h27   #2
Richard Heathfield
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: K&R2 Exercise 4-12

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
  Réponse avec citation
Vieux 13/04/2008, 11h05   #3
Bartc
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: K&R2 Exercise 4-12


"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


  Réponse avec citation
Vieux 13/04/2008, 11h57   #4
Ben Bacarisse
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: K&R2 Exercise 4-12

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.
  Réponse avec citation
Vieux 15/04/2008, 13h44   #5
Martin
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: K&R2 Exercise 4-12

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

  Réponse avec citation
Vieux 15/04/2008, 19h06   #6
Flash Gordon
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: K&R2 Exercise 4-12

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
  Réponse avec citation
Vieux 15/04/2008, 23h04   #7
Dann Corbit
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: K&R2 Exercise 4-12

"Flash Gordon" <spam@flash-gordon.me.uk> wrote in message
newse7fd5xqel.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 **
  Réponse avec citation
Vieux 15/04/2008, 23h12   #8
Peter Nilsson
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: K&R2 Exercise 4-12

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
  Réponse avec citation
Réponse


Outils de la discussion

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Trackbacks are oui
Pingbacks are oui
Refbacks are oui


Fuseau horaire GMT +1. Il est actuellement 07h14.


Édité par : vBulletin® version 3.7.2
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0 RC5 Tous droits réservés.
Version française #16 par l'association vBulletin francophone
PHWinfo est un site Éducation Sans Frontières
Ad Management by RedTyger
©Tous droits réservés par les parties respectives
Page generated in 0,14129 seconds with 16 queries