IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Votre avis sur un code de conversion


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau candidat au Club
    Homme Profil pro
    Technicien réseau
    Inscrit en
    Janvier 2016
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Belgique

    Informations professionnelles :
    Activité : Technicien réseau

    Informations forums :
    Inscription : Janvier 2016
    Messages : 1
    Par défaut Votre avis sur un code de conversion
    Bon(jour)/soir à tous,

    Afin d'éviter les "scanf" en C, et ne souhaitant pas absorber différents code du web, j'ai fais un petit quelque chose.
    Le code se divise en 2 parties :
    1. fonctions.h
    2. source.c


    Ceci afin de le rendre plus lisible.

    Je me permet alors de vous le publier ici, pour en obtenir des commentaires sur la logique, et vos conseils qui pourrait permettre de l'améliorer et moi aussi.

    Merci à vous.

    Fonctions.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    #include <string.h>
    #include <stdio.h>
    #define TRUE 1
    #define FALSE 0
     
    void menu()
    {
    	char t0[] = ("********************************");   //Un Affichage basic me direz vous. 
    	char t1[] = ("*                              *");
    	char t2[] = ("*         Conversion           *");
    	char t3[] = ("*                              *");
    	char t4[] = ("********************************");
     
    	puts(t0); 
    	puts(t1); 
    	puts(t2); 
    	puts(t3);
    	puts(t4); 
    }
     
    short saisie(char *nb,int lgt)
    {
    	short i,j; 
    	short taille=0; 
    	char comp[] = { '0','1','2','3','4','5','6','7','8','9','/0' }; //Tableau de comparaison CHAINE de Char et nombre. 
     
    	for (i = 0; i < lgt; i++)  //lgt = longueur de la chaine original envoyée en 2nd paramètre. 
    	{
    		for (j = 0; j < 11; j++)
    		{
    			if (*(nb + i) == comp[j]) //nb = Chaine original envoyé en 1er paramétre. 
    			{
    				taille ++; //Si la comparaison est vraie, on incrémente la taille. ===> Cette variable permettra de vérifier si le nbre de caractère est bon. 
    				j = 11; //Et si Taille n'est pas bon, c'est qu'un caractère n'est pas un nombre.  
    			}
    		}
    	}
     
    	if (taille == lgt)
    		return TRUE;
    	else
    		return FALSE; 
    }
     
    int conversion(char *lg)
    {
    	int i, j, k, z;
    	int nbre = 0;
    	char comp[] = { '0','1','2','3','4','5','6','7','8','9' }; //Chaine de comparaison. 
     
    	for (i = 0; i < 10; i++)
    	{
     
    		for (j = 0; j < 10; j++)
    		{
    			if (comp[j] == *(lg + i)) // Nul besoin de commentaire ici. #Paradox
    			{
    				for (k = 0, z = 1; k < strlen(lg) - (i + 1); k++) z *= 10; // La variable z permet de bien placer les unité diziaine et centaine. 
    				nbre += j * z;
    				z = 1; //On le réinitialise a 1. 
    			}
    		}
     
    	}
     
    	return nbre; //On retourne la variable mais convertie en int. 
    }
     
    void EntrerNbre(char *lg)
    {
    	char clav[10];
    	short pass = 0;
    	short gardien, i;
     
    	printf("\nSaisissez un nombre > ");
    	do
    	{
    		if (pass)
    		{
    			printf("Vous n'avez pas ecris un nombre. vous avez entre %s \n", clav);
    		}
    		gets(clav);
    		gardien = saisie(&clav, strlen(clav));
    		pass++;
    	} while (!gardien);
     
    	strcpy(lg, clav);
     
    }
    Le source.c
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include "fonctions.h"
    #include <stdio.h>
    void main()
    {
    	char nbr[10];
    	int i;
    	menu();
    	EntrerNbre(&nbr);
    	i = conversion(&nbr);
    	printf("\n\n====> %d <======\n", i);
    }

  2. #2
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut


    Par où je commence ?

    gets, hein ? On est d'accord. Tu trouveras probablement dans la FAQ la raison pour laquelle cette fonction est à proscrire.

    Les alternatives à scanf existent ! Pour la simple et bonne raison que scanf n'est justement pas conçue pour faire de la saisie au clavier. On réalise en général une saisie portable via fgets. L'analyse de chaîne de caractères et la conversion en nombre se fait ensuite via sscanf ou strto*.

    En ce qui concerne la logique proprement dite : il n'y a aucune cohérence au sein de ton programme. Tu valides d'abord une conversion en tentant de l'effectuer, via saisie puis.. tu effectues à nouveau cette conversion à l'aide d'une autre fonction presque identique : conversion. Pourquoi ? Sans compter que la première demande la longueur de la chaîne passée en paramètre, qu'on lui fournit via strlen, alors que la seconde invoque directement strlen.

    Revois déjà ton programme et nous continuerons à partir de là.

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 151
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 151
    Billets dans le blog
    4
    Par défaut
    Normalement le but d'un découpage c'est de mettre les prototypes dans les .h à inclure et les implémentations dans les .c qui seront compilés et liés...
    Protège tes define pour éviter les surprises. Les valeurs devraient toujours être entres parenthèses.
    Quitte à définir true et false, autant allé au bout et définir bool.
    Tu n'as pas besoin de 5 variables pour afficher 5 lignes..
    saisie est sensé faire quoi ? Ce n'est pas une saisie en tous cas. Le code ressemble à une implémentation chelou de check qu'une chaîne est un nombre.
    conversion a au moins un nom qui semble être ce qu'elle fait. Mais l'implémentation est vraiment bof en plus de traiter arbitrairement 10 caractères...
    EntrerNbre fait de la saisie, de la vérification, de l'affichage de résultat, puis finit avec une copie inutile et inexplicable dans une variable locale
    nbr est déjà un pointeur, inutile de prendre prendre son adresse, je suis même un peu surpris que ça passe, ca devrait au moins émettre un warning. Les affiches-tu ?

    Il n'y a aucune homogénéité dans les nommages.


    http://c.developpez.com/faq/?page=Bo...aveur-de-fgets
    http://c.developpez.com/faq/?page=Bo...utiliser-scanf
    http://c.developpez.com/faq/?page=Ge...iere-securisee
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  4. #4
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Citation Envoyé par Bousk Voir le message
    nbr est déjà un pointeur, inutile de prendre prendre son adresse, je suis même un peu surpris que ça passe
    nbr est un tableau, du coup nbr et &nbr renvoient la même adresse. C'est un exotisme du langage, comme souvent avec ce qui touche aux tableaux en C. C'est mieux expliqué par cette réponse sur SO : https://stackoverflow.com/a/2528328 .

  5. #5
    Membre Expert Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    785
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 785
    Par défaut
    Hello,

    - apparemment, tu ne connais pas la fonction isdigit(), sinon tu l'aurais employée dans saisie(), qui se serait alors résumée à 4 lignes
    - tu ne connais pas non plus strtoul(), qui remplacerait avantageusement ta gymnastique avec i, j et z dans conversion()
    - et il existe en C, depuis 1999, soit depuis presque 20 ans, un type bool, que l'on trouve dans <stdbool.h>. Et, bien sur, true et false y sont définis
    - ça a été dit, mais: une fonction menu() qui ne propose aucun menu, une fonction saisie() qui ne saisit rien....

  6. #6
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Bonjour

    Le principal semble avoir été déjà dit. Surtout le fait qu'on ne met jamais de code C dans du .h
    Maintenant quelques détails. Par exemple perso je pense que ton
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if (taille == lgt)
    		return TRUE;
    	else
    		return FALSE;
    se remplace avantageusement par return taille == lgt ?TRUE :FALSE voire même return taille == lgt. Et tu peux remplacer ton char comp[] = { '0','1','2','3','4','5','6','7','8','9','/0' } par un élégant char comp[] = "0123456789" voire même directement char *comp = "0123456789" puisque tu ne modifies pas son contenu. Et ton j=11 (nombre magique) peut alors devenir j=strlen(comp) + 1 ou plus simmplement tu mets un bon vieux break bien efficace et bien explicite.

    De plus, ton *(nb + i) ne gagne absolument rien en vitesse par rapport à un nb[i] bien plus lisible.
    On a souvent l'habitude de dire qu'un pointeur va plus vite qu'un tableau. C'est vrai mais seulement si le pointeur est déjà placé à la bonne adresse. Par exemple char *pt=nb+i fera ensuite que tous les accès *pt seront plus rapide que nb[i]. En revanche, les instructions *(nb + i) et nb[i] prennent le même temps car dans les deux cas l'opération est la même (se placer au début et décaler de "i" cases).

    Donc finalement ta fonction devient ceci
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    short saisie(char *nb, size_t lgt)
    {
    	size_t i; 
    	size_t taille; 
    	char *pt1;
    	char *pt2;
     
    	char *comp="0123456789";
     
    	for (i = 0, pt1=nb, taille=0; i < lgt; i++, pt1++)
    	{
    		for (pt2=comp; *pt2 != '\0'; pt2++)
    		{
    			if (*pt1 == *pt2)	// Ici ça va effectivement plus vite car les pointeurs sont déjà à la bonne position
    			{
    				taille++;
    				break;
    			}
    		}
    	}
     
    	return taille == lgt;
    }

    Et sinon le plus gros (que personne n'a vu même pas moi car je viens éditer mon post pour le dire): main() n'est pas de type "void" !!!!!

    PS: z = 1; //On le réinitialise a 1. => un commentaire efficace et explicite...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

Discussions similaires

  1. Votre avis sur mes codes
    Par herzak dans le forum Langage
    Réponses: 2
    Dernier message: 28/01/2011, 11h41
  2. [XL-2003] Votre avis sur mon code en VBA ?
    Par [ZiP] dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 02/03/2010, 13h56
  3. MAX_CONNECTIONS: votre avis sur ce code
    Par Zartan dans le forum Administration
    Réponses: 2
    Dernier message: 31/01/2010, 04h34
  4. [FFT] Votre avis sur mon code
    Par deubelte dans le forum C++
    Réponses: 1
    Dernier message: 10/02/2007, 20h14
  5. [Code Prof]votre avis sur un code?
    Par granquet dans le forum Réseau
    Réponses: 6
    Dernier message: 11/04/2006, 20h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo