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 :

Afficher les informations d'un utilisateur


Sujet :

C

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2015
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Guinée

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2015
    Messages : 1
    Points : 2
    Points
    2
    Par défaut Afficher les informations d'un utilisateur
    Bonjour tout le monde, je suis debutant et je veux vraiment comprendre la programmation mais voici mon tout premier code qui me donne les mots de tete alors j'ai non seulement besoin de conseil mais egalement corrigé ce code pour moi et explique moi d'ou vient le probleme et pourquoi.
    MON SOUHAIT : je veux que ce programme affiche les informations elementaires saisie par l'utilisateur
    voici le code:

    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
    int main(int argc, char *argv[]) {
    	char* nom;
    	char* prenom;
    	char* sexe;
    	char* profession;
    	puts("NOMS?");
    	scanf("%s",&nom);
    	puts("PRENOMS?");
    	scanf("%s",&prenom);
    	puts("SEXE? MONSIEUR OU MADAME?");
    	scanf("%s",&sexe);
    	puts("PROFESSION ");
    	scanf("%s",&profession);
    	printf("voici vos informations personnelle sont:\n");
    	printf("nom: %s\n",nom);
    	printf("prenom: %s\n",prenom);
    	printf("sexe: %s\n",sexe);
    	printf("profession: %s\n",profession);
    	return 0;
     
     
    }

  2. #2
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    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 690
    Points : 30 986
    Points
    30 986
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par LAMINE12345 Voir le message
    mais egalement corrigé ce code pour moi et explique moi d'ou vient le probleme et pourquoi.
    Bonjour

    Bel effort. Ton code est pas mal. Il y a juste deux deux problèmes
    Le premier (problème majeur): tu ne peux pas mettre de l'information dans un pointeur qui n'a pas de mémoire (tous tes char *).
    Voici ce qui se passe: quand tu écris char *nom, tu définis une variable "nom" contenant n'importe quelle valeur (principe qui prévaut pour toute variable locale). Or, quand tu demandes scanf("%s", nom) tu demandes à la fonction scanf d'aller stocker de l'information à l'adresse située dans "nom" ; donc en fait dans une adresse totalement aléatoire et pouvant pointer n'importe où dans la mémoire. Il y a alors beaucoup de risques que cet endroit corresponde précisément à la mémoire d'une autre variable (que tu vas pourrir), ou bien à un endroit par chance libre mais qui sera alloué plus tard à une autre variable (qui viendra alors pourrir ton nom saisi) ou plus simplement un endroit qui t'es interdit (memory fault). Et si par chance rien de tout cela ne se produit, ben cela ne garantit en rien que cela ne se produira pas plus tard. C'est ce qu'on nomme "comportement indéterminé" (car imprévisible).

    Solutions
    1. tu définis non pas un pointeur, mais un tableau => ex char nom[100]; scanf("%s", nom). Là tu es certain que à cet endroit tu as 100 caractères réservés dans lequel tu pourras écrire allègrement et sans souci. Bien entendu ce n'est pas parfait (rien n'interdit à l'utilisateur, lorsqu'il saisit son nom, de saisir plus de 100 caractères) mais hormis certains puristes psychorigides qui évoluent dans ce forum avec leur triste figure en s'imaginant être les représentants de la très sainte inquisition du C, personne n'ira te reprocher ce type de code quand tu es débutant. Ensuite, plus tard, tu apprendras à faire des saisies contrôlées.
    2. tu demandes au système de t'allouer n caractères (via malloc) et tu récupères dans ton pointeur l'adresse allouée => ex char *nom=malloc(100 * sizeof(char)); scanf("%s", nom). Le résultat sera le même mais introduira plus de contraintes car il te faut 1) vérifier la réussite de malloc et 2) libérer la zone allouée en fin d'utilisation. C'est pour ça qu'on préfère n'utiliser cette solution qu'à partir du moment où on ne connait pas à l'avance la taille voulue (ex: taille calculée) car quand on la connait (ici 100) la première solution est bien plus facile à mettre en oeuvre.
    3. tu considères que le comportement indéterminé te donne quand même une chance que ça fonctionne et tu ne changes rien (banco !!! ). Après tout, même en C t'as le droit d'avoir ton exemplaire de roulette russe...

    Donc pour résumer: quand tu définis un pointeur style char *pt, tu n'as absolument pas le droit d'aller taper dans la zone "pt" tant que tu n'auras pas la certitude que "pt" contienne une adresse valide.
    Exemple
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    char nom[100];
    char *pt;
    pt=nom;    // Ici je suis certain que "pt" contient une adresse valide (l'adresse du tableau "nom")
    scanf("%s", pt); // ok

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    char *pt;
    pt=malloc(100 * sizeof(char));
    if (pt != NULL) {    // Ici je suis certain que "pt" contient une adresse valide (l'adresse de la zone allouée)
        scanf("%s", pt); // ok
        free(pt);
    }

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void remplir(char *pt)
    {
        // Ici je suis certain que "pt" contient une adresse valide parce qu'il me vient de l'extérieur (et que je présume en écrivant ma fonction que tout ce qui me vient de l'extérieur est présumé correct)
        scanf("%s", pt); // ok
    }


    Le second (problème mineur): on ne met pas de "&" devant les noms de pointeurs ou des noms de tableaux car justement ce sont déjà des pointeurs donc déjà des adresses (regarde bien mes exemples). En effet, quand tu écris char nom[100], le token "nom" équivaut à l'adresse du premier élément du tableau => nom=&nom[0] (et l'arithmétique des pointeurs permet d'étendre cette règle à tout élément => (nom+x)=&nom[x]).
    Donc soit tu écris scanf("%s", &nom[0]), soit tu écris plus simplement son équivalent scanf("%s", nom). Mais tu ne peux pas écrire scanf("%s", &nom). C'est un problème mineur parce qu'en général le compilateur le détecte et le corrige mais bon, autant bien écrire dès le départ.
    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]

  3. #3
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    En fait, c'est là un des plus gros problèmes du langage C pour les débutants: Il n'y a pas de fonction toute faite pour récupérer sur l'entrée standard une ligne de texte de longueur arbitraire. Contrairement à des langages comme C++ ou C#.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

Discussions similaires

  1. Réponses: 0
    Dernier message: 29/05/2016, 23h00
  2. [Débutant] Afficher les informations d'utilisateur courant ASP.NET MVC Entity framework
    Par risutsukoo dans le forum Développement Web avec .NET
    Réponses: 0
    Dernier message: 11/05/2015, 21h15
  3. Réponses: 2
    Dernier message: 17/05/2006, 15h49
  4. afficher les informations texte depuis mysql
    Par arti2004 dans le forum SQL Procédural
    Réponses: 2
    Dernier message: 26/02/2006, 16h54
  5. Afficher les informations du système
    Par orisis dans le forum Windows
    Réponses: 8
    Dernier message: 10/06/2004, 15h10

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