Partage
  • Partager sur Facebook
  • Partager sur Twitter

[zConvert] Exercice pour débutants

Bonne chance à vous :)

13 juillet 2010 à 19:22:51

Bonjour.
Je m'y essaie mais je pense que je n'ai pas très bien réussis l'exercice :
#include <stdio.h>

char* zConvertInt(int nombre)
{
    static char nb[50]={0};
    sprintf(nb,"%d",nombre);
    return nb;
}


char* zConvertDouble(double nombre)
{
    static char nb[50]={0};
    sprintf(nb,"%f",nombre);
    return nb;
}

int main()
{
    char *nint, *ndouble;
    nint= zConvertInt(10);
    ndouble= zConvertDouble(10.5899);
    printf("%s %s",nint,ndouble);
    return 0;
}


Je n'ai pas réussis à me passer du mot clé static.
Si quelqu'un peut m'aider à améliorer mon code, je suis partant.

Emmflo

@HighTam : Effectivement, c'était trop facile. Bon, je m'y remet.
  • Partager sur Facebook
  • Partager sur Twitter
13 juillet 2010 à 19:26:58

@Emmflo : L'idée de l'exercice est de faire ce que te fait sprintf() en quelque sorte ;)
  • Partager sur Facebook
  • Partager sur Twitter
13 juillet 2010 à 19:39:34

#include <stdio.h>
#include <limits.h>

void convertir(int n, char *res)
{
    char *convertir(unsigned n, char *s)
    {
        if (n < 10)
            return *s++ = n + '0', s;
        *(s = convertir(n / 10, s)) = n % 10 + '0';
        return s + 1;
    }

    if (n < 0)
        *res++ = '-', n = -n;
    *convertir(n, res) = 0;
}

int main (void)
{
  char res[20];

  convertir(INT_MAX, res);
  puts(res);
  convertir(INT_MIN, res);
  puts(res);
  convertir(0, res);
  puts(res);
  return 0;
}

C'est moche, pas standard et inutilement compliqué, mais quel intérêt de poster un code que quelqu'un a déjà fait?
  • Partager sur Facebook
  • Partager sur Twitter
14 juillet 2010 à 1:52:32

Citation : Marc Mongenet


@manrugby: *(chaine++)+=reste+'0'; devrait être *(chaine++)=reste+'0'; . Cela dit, tu utilises inutilement des expressions trop compliquées.


Elle est ou la complexité ? développe stp.

voici ma deuxième tentative:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void permuter(char *a,char *b){

  *a += *b;
  *b = *a-*b;
  *a = *a-*b;
}

void convertir(int n, char* chaine)
{
    char* saveStr=chaine;
    int reste=n;
    int i=0,j=0;

    while(n)
    {
        *(chaine++)=(reste%=10)+'0';
         reste=n/=10;
    }
    *(chaine)++='\0';
    j=strlen(saveStr)-1;

    while(i<j) permuter(&saveStr[i++],&saveStr[j--]);

}

int main(void)
{
    int n;
    char chaine[50] = "";

    scanf("%d", &n);

    convertir(n, chaine);

    printf("%s", chaine);

    return EXIT_SUCCESS;
}
  • Partager sur Facebook
  • Partager sur Twitter
14 juillet 2010 à 10:02:40

Citation : manrugby

Elle est ou la complexité ? développe stp.


Voilà une version plus simple de ton code, où le comportement de la fonction permuter n'est pas indéterminé, et qui marche quand on tape 0.
#include <stdio.h>
#include <stdlib.h>


void permuter(char *a, char *b)
{
	char swap = *b;
	*b = *a;
	*a = swap;
}

void convertir(int n, char *chaine)
{
	char *saveStr = chaine;
	int i = 0, j;

	do {
		*chaine++ = n % 10 + '0';
		n /= 10;
	} while (n);

	*chaine = '\0';
	j = chaine - saveStr - 1;

	while (i < j) permuter(&saveStr[i++], &saveStr[j--]);
}

int main(void)
{
    int n;
    char chaine[50] = "";

    scanf("%d", &n);
    convertir(n, chaine);
    puts(chaine);

    return EXIT_SUCCESS;
}
  • Partager sur Facebook
  • Partager sur Twitter
14 juillet 2010 à 19:07:27

Bonsoir.

Voici une nouvelle version :
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

char *zConvertInt(int nombre)
{
    static char nb[50];
    int i=0, j=0;
    for(i=50; i>=0;i--)
    {
        nb[j]=(nombre / (int)pow(10,i) %10)+'0';
        j++;
    }
    return nb;
}
int main()
{
    char* nb;
    nb=zConvertInt(825148941);
    printf("%s", nb);
    return 0;
}


Elle mérite d'avoir des améliorations (suppression des 0 en trop...).

Emmflo
  • Partager sur Facebook
  • Partager sur Twitter
14 juillet 2010 à 19:14:23

Citation : thecoun

  • La ligne de preprocesseur #define T (int)floor(log10(abs(n+1)))+1 ne me plais pas car elle utilise 'n' qui dépend d'un contexte précis..
  • Tu alloues T cases et tu place '\0' sur la T + 1 ième case...

Pour le prépocesseur, n est une variable c'est ça ?
Pour l'allocation je crois ne pas comprendre ce que tu dis. J'alloue T cases, et je place le caractère de fin de chaîne sur la T-ième case.
  • Partager sur Facebook
  • Partager sur Twitter
14 juillet 2010 à 20:29:12

Citation : Emmflo

Elle mérite d'avoir des améliorations (suppression des 0 en trop...).


Hello, il faudrait surtout indiquer la fin de la chaine par un caractère nul. :-°

@Colb-Seton: s[T] est la T+1 ième case.
  • Partager sur Facebook
  • Partager sur Twitter
14 juillet 2010 à 22:21:55

Bonsoir.
C'est (un peu) mieux comme ça?
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

char *zConvertInt(int nombre)
{
    static char nb[50];
    int i=0, j=0;
    for(i=49; i>=0;i--)
    {
        nb[j]=(nombre / (int)pow(10,i) %10)+'0';
        j++;
    }
    nb[50]='\0';
    return nb;
}
int main()
{
    char* nb;
    nb=zConvertInt(825148941);
    printf("%s", nb);
    return 0;
}



Emmflo
  • Partager sur Facebook
  • Partager sur Twitter
14 juillet 2010 à 23:05:35

Citation : Emmflo

C'est (un peu) mieux comme ça?


Plutôt un peu pire... Le caractère nul est placé juste après le tableau. :(
  • Partager sur Facebook
  • Partager sur Twitter
15 juillet 2010 à 11:53:56

Bonjour.
Effectivement...
Bon, je réessaie :
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

char *zConvertInt(int nombre)
{
    static char nb[50];
    int i=0, j=0;
    for(i=48; i>=0;i--)
    {
        nb[j]=(nombre / (int)pow(10,i) %10)+'0';
        j++;
    }
    nb[49]='\0';
    return nb;
}
int main()
{
    char* nb;
    nb=zConvertInt(825148941);
    printf("%s", nb);
    return 0;
}

J'espère que cette fois-çi, c'est mieux.

Emmflo
  • Partager sur Facebook
  • Partager sur Twitter
15 juillet 2010 à 13:23:53

Citation : Emmflo

J'espère que cette fois-çi, c'est mieux.Emmflo


C'est correct dans le cas (improbable) où le nombre est converti en une chaine de 49 caractères. Sinon, c'est mal placé.
Il suffirait de tester un tout petit peu sérieusement le code pour s'en rendre compte... :-°
  • Partager sur Facebook
  • Partager sur Twitter
19 juillet 2010 à 14:46:49

Moi j'ai fais comme ça en une ligne, mais apparemment j'ai pas le droit :euh:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

void convertion(double nb, char chaine[])
{
    sprintf(chaine, "%f", nb);
}

int main(void)
{
    double nb;
    char chaine[50] = "";

    printf("Entrez votre nombre : ");
    scanf("%lf", &nb);

    convertion(nb, chaine);

    printf("Et voici le nouveau nombre : %s ! Vous y avez vu que du feu et pourtant\n"
           "on a convertit un double en char >_<", chaine);

    return EXIT_SUCCESS;
}
  • Partager sur Facebook
  • Partager sur Twitter
19 juillet 2010 à 18:24:34

L'intérêt c'est de programmer une fonction qui le fait, pas d'utiliser une fonction déjà faite. Après, rien ne l'interdit dans l'exercice donc ton code est tout à fait correct.
Le but d'un exercice, c'est de faire par ses propres moyens, pas d'utiliser des choses déjà faites. :)
  • Partager sur Facebook
  • Partager sur Twitter
20 juillet 2010 à 7:09:42

#include <stdio.h>
#include <stdlib.h>

static void
_swap (char *a, char *b) {
    if (*a == *b)
        return ;
    *a ^= *b;
    *b ^= *a;
    *a ^= *b;
}

static void
_adjust (char *str, size_t len, size_t start) {
    size_t  i = 0, j;

    while (i < len && !str[i])
        ++i;
    for (j = start ; str[i] ; ++i, ++j)
        _swap(&str[i], &str[j]);
}

static int
my_modulo (long a, long b) {
    return a - (a / b) * b;
}

static void
_conv (long n, char *str, size_t i) {
    str[i] = labs(my_modulo(n, 10)) + '0';
    if (n / 10)
        _conv(n / 10, str, i - 1);
}

static size_t
numlen (long n, size_t count) {
    return n / 10 ? numlen(n / 10, count + 1) : count + 1;
}

static char *
zConvert (long n) {
    size_t  len = numlen(n, 0);
    char    *str = calloc(len + 2, 1);

    if (!str)
        exit(EXIT_FAILURE);
    _conv(n, str, len);
    if (n < 0)
        str[0] = '-';
    else {
        _adjust(str, len, 0);
        str = realloc(str, len + 1);
        if (!str)
            exit(EXIT_FAILURE);
    }
    return str;
}

Mais chwi pas content de ce que j'ai fait, j'ai l'impression de pouvoir faire plus simple --'
  • Partager sur Facebook
  • Partager sur Twitter
20 juillet 2010 à 18:30:14

C'est une blague le numlen et my_modulo ? :lol:
A mon avis tu peux faire beauuuucoup plus simple. :-°
  • Partager sur Facebook
  • Partager sur Twitter
20 juillet 2010 à 19:38:24

Le my_modulo non, c'est pour eviter le souci d'implementation comme l'a dit Marc plus haut.. je sais que
my_modulo(a, b) = -my_modulo(-a, b)
et que
my_modulo(a, b) = a % b
Apres je peux afficher INT_MIN sans ce souci en C89 ;)

Pour le numlen en effet, j'ai pas trouve mieux (faut dire que j'ai pas beaucoup reflechi ^^ )
  • Partager sur Facebook
  • Partager sur Twitter
20 juillet 2010 à 19:42:44

Pour numlen : log10(n)+1 nan ?
  • Partager sur Facebook
  • Partager sur Twitter
20 juillet 2010 à 19:46:40

Flemme d'inclure math.h.. ca m'agace deja d'avoir a inclure stdlib.. je pense que je vais gerter l'alloc et je vais faire une taille_max butoire.. ^^
  • Partager sur Facebook
  • Partager sur Twitter
20 juillet 2010 à 19:57:35

mon code, il gère les nombres negatifs, j'ai pas voulu inclure math.h entre autre, et marche que pour des architectures 32bits...
et je me suis pas cassé la tête avec les math... c'est les vacances =)
sinon j'ai vu une fonction pow sur un code de quelqu'un, elle est pas extrêmement lourde, cette fonction?

#include <stdio.h>
#include <stdlib.h>

void convertir(int n, char * chaine) 
{
  int cpt = 0;
  int i,temp,bool = 0;
  if(n<0)
  {
     chaine[cpt++]='-';
     n = -n;     
  }
  /*le int en 32bit va jusqu'a 2147483647*/
  for(i=1000000000;i>=10;i/=10)
  {
     temp = n/i;
     if(bool || temp)
     {                           
        chaine[cpt++]= (temp + 48);
        bool = 1;
     }
     n = n%i;
     
  }
  chaine[cpt++] = (char) n + 48;
  chaine[cpt]=0;
  
}

int main(int argc,char * argv[]) 
{
  int n;
  char chaine[50] = "";
  scanf("%d", &n);
  convertir(n, chaine);
  printf("%s\n", chaine);
  system("pause");
  return EXIT_SUCCESS;
}
  • Partager sur Facebook
  • Partager sur Twitter
20 juillet 2010 à 20:24:40

tu as une approche originale Oo je vais lire tout ca, il gere INT_MIN?
  • Partager sur Facebook
  • Partager sur Twitter
20 juillet 2010 à 20:30:14

Histoire de participer :p :
#include <stdio.h>
#include <math.h>

void
_zConvert (int n, char * chaine) {
    *chaine = n % 10 + '0';
    if (n/10)
        _zConvert(n/10, chaine - 1);
}

void
zConvert(int n, char * chaine) {
    size_t len = log10(n) + 1;
  
    if (len > 49) {
    	puts("zConvert : Overflow attempt.");
 	return;
    } else _zConvert(n, chaine + len - 1);
}


int
main (void) {
    char str[50] = {0};
    int n;
	
    scanf("%d", &n);
    zConvert(n, str);

    printf("%s\n", str);
	
    return 0;
}
  • Partager sur Facebook
  • Partager sur Twitter
20 juillet 2010 à 20:34:46

#include <stdio.h>

static void
_adjust (char *str, size_t len, size_t start) {
    size_t  i = 0, j;
    char    temp;

    while (i < len && !str[i])
        ++i;
    for (j = start ; str[i] ; ++i, ++j) {
        temp = str[i];
        str[i] = str[j];
        str[j] = temp;
    }
}

static int
my_modulo (long a, long b) {
    return a - (a / b) * b;
}

static int
_abs (int a) {
    return a < 0 ? -a : a;
}

static void
_conv (long n, char *str, size_t i) {
    str[i] = _abs(my_modulo(n, 10)) + '0';
    if (n / 10)
        _conv(n / 10, str, i - 1);
}

#define SMAX    16

static char *
zConvert (long n, char str[]) {

    _conv(n, str, SMAX - 2);
    _adjust(str, SMAX, 1);
    if (n < 0)
        str[0] = '-';
    else
        _adjust(str, SMAX, 0);
    return str;
}

Nouveau code un chouia plus simple ;)

@ Lithrein : et les negatifs ? ^^
  • Partager sur Facebook
  • Partager sur Twitter
20 juillet 2010 à 20:39:16

Citation : Adroneus

@ Lithrein : et les negatifs ? ^^


Flemme, mais bon je peux les rajouter ;)
  • Partager sur Facebook
  • Partager sur Twitter
20 juillet 2010 à 20:40:20

Beeeen ^^ c'pas grand chose, mais comme ca tu pourras aussi gerer le cas n = INT_MIN qui posait probleme ;)
  • Partager sur Facebook
  • Partager sur Twitter
20 juillet 2010 à 21:18:22

Je suis un peu surpris que personne n'ai essayé de gérer les nombres flottants :o . Ca aurait été intéressant quand même.
  • Partager sur Facebook
  • Partager sur Twitter
20 juillet 2010 à 21:23:23

L'exo est pas encore fini si? ^^
  • Partager sur Facebook
  • Partager sur Twitter
20 juillet 2010 à 21:41:58

Citation : Adroneus

L'exo est pas encore fini si? ^^

Non mais personne n'a encore rien proposé... Je vais ptete essayer, mais ça doit pas être facile de faire quelque chose de propre.
  • Partager sur Facebook
  • Partager sur Twitter
20 juillet 2010 à 21:53:36

je me teste sur les float, bah avec les imprécisions due au float bah ca donne pas tout à fait la chaine saisie :/
on peut travailler sur les doubles?
  • Partager sur Facebook
  • Partager sur Twitter
20 juillet 2010 à 22:14:58

bien sur c'meme conseille je pense
  • Partager sur Facebook
  • Partager sur Twitter