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 :

Bug de la fonction system en C :-(


Sujet :

C

  1. #1
    Futur Membre du Club
    Inscrit en
    Septembre 2008
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 14
    Points : 6
    Points
    6
    Par défaut Bug de la fonction system en C :-(
    Bonjour tout le monde !

    En cours, je suis sur des petits projets pour mon BTS... Or l'un d'eux va me rendre zinzin

    Je pense que la commande system () en est la source, mais comment résoudre ce problème ? Je n'ai pas la réponse. C'est pourquoi je viens à vous

    Mon programme permet de gérer les ordinateurs d'un réseau : il stock dans un fichier les données (adresse IP, nom du poste etc.) et l'une de ses fonctions consiste à effectuer un ping pour connaître l'état de la machine (en ligne / hors ligne).

    Pour cela, j'utilise la fonction system... Mais quelque chose de pas cool se produit ; explications :

    Voici mon code source :
    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
    void tester (char* fichierIP, char* fichierOK, char* fichierNOK)
    {
        Ordi* TabOrdi = chargerFichier(fichierIP);
        Ordi TabOrdiok[100];
        Ordi TabOrdiNok[100];
        int i = 0;
        int resultat = 0;
        char cmd[50];
     
        for (i=0;i <= nbreElement;i++) // nbreElement contient le nombre d'enregistrement du fichierIP
        {
            printf("---------------\n");
     
            // Je crée ma commande de ping et la stock dans cmd
            sprintf(cmd, "ping -n 1 %d.%d.%d.%d > NULL", TabOrdi[i].IPOrdi.ip1, TabOrdi[i].IPOrdi.ip2, TabOrdi[i].IPOrdi.ip3, TabOrdi[i].IPOrdi.ip4);
     
            // Je test
            printf("cmds : %s\n", cmd);
     
            // J'exécute ma commande et récupère dans "resultat" le code retourné par system()
            resultat = system (cmd);
     
            // J'affiche ce code résultat (pour voir si tout fonctionne)
            printf("resultat : %d\n", resultat);
        }
    }
    Et là, voici le résultat ! Pas très jolie ...

    ---------------
    cmds : ping -n 1 123.12.123.10 > NULL
    resultat : 0
    ---------------
    cmds : ping -n 1 4980802.1999633846.1988581918.48 > NULL
    resultat : 1
    ---------------
    cmds : ping -n 1 0.0.2679004.1988581993 > NULL
    resultat : 1
    ---------------
    cmds : ping -n 1 0.0.0.0 > NULL
    resultat : 1
    ---------------
    cmds : ping -n 1 1988583728.88.1988583756.0 > NULL
    resultat : 1
    ---------------
    cmds : ping -n 1 0.2678220.0.0 > NULL
    resultat : 1
    ---------------
    cmds : ping -n 1 0.0.0.0 > NULL
    resultat : 1
    Comme on peut voir mes adresses IP sont pas très... Bref ! Y'a un souci !

    Je commente la ligne où je fais mon system ()

    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
    void tester (char* fichierIP, char* fichierOK, char* fichierNOK)
    {
        Ordi* TabOrdi = chargerFichier(fichierIP);
        Ordi TabOrdiok[100];
        Ordi TabOrdiNok[100];
        int i = 0;
        int resultat = 0;
        char cmd[50];
     
        for (i=0;i <= nbreElement;i++) // nbreElement contient le nombre d'enregistrement du fichierIP
        {
            printf("---------------\n");
     
            // Je crée ma commande de ping et la stock dans cmd
            sprintf(cmd, "ping -n 1 %d.%d.%d.%d > NULL", TabOrdi[i].IPOrdi.ip1, TabOrdi[i].IPOrdi.ip2, TabOrdi[i].IPOrdi.ip3, TabOrdi[i].IPOrdi.ip4);
     
            // Je test
            printf("cmds : %s\n", cmd);
     
            // J'exécute ma commande et récupère dans "resultat" le code retourné par system()
            //resultat = system (cmd);
     
            // J'affiche ce code résultat (pour voir si tout fonctionne)
            printf("resultat : %d\n", resultat);
        }
    }
    Et là, miracle tout s'affiche correctement ! Mais je n'ai pas de ping de fait !

    ---------------
    cmds : ping -n 1 123.12.123.10 > NULL
    resultat : 0
    ---------------
    cmds : ping -n 1 192.168.12.3 > NULL
    resultat : 0
    ---------------
    cmds : ping -n 1 192.168.13.4 > NULL
    resultat : 0
    ---------------
    cmds : ping -n 1 192.168.12.6 > NULL
    resultat : 0
    ---------------
    cmds : ping -n 1 192.168.14.5 > NULL
    resultat : 0
    ---------------
    cmds : ping -n 1 192.168.14.8 > NULL
    resultat : 0
    ---------------
    cmds : ping -n 1 192.168.1.96 > NULL
    resultat : 0
    Bizarre n'est-ce pas ?

    Avez-vous une idée pour solutionner mon problème ?


    Merci d'avance

  2. #2
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2010
    Messages
    254
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2010
    Messages : 254
    Points : 538
    Points
    538
    Par défaut
    Vérifie que les tableaux que tu utilise pour remplir cmd soit bien remplis.
    "L'insanité consiste à répéter la même action dans l'espoir d'aboutir à un résultat différent" Albert Einstein
    ----------------------
    T.O.A.O 6-MarViN

  3. #3
    Futur Membre du Club
    Inscrit en
    Septembre 2008
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 14
    Points : 6
    Points
    6
    Par défaut
    Bien... Je dirais qu'ils sont bien remplis vu que lorsque je commente system (), on voit bien les valeurs =) (d'où mon expérience de mise en commentaire de system ())

  4. #4
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2010
    Messages
    254
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2010
    Messages : 254
    Points : 538
    Points
    538
    Par défaut
    Essaye de remettre ta chaine à zéro après ton system:
    Je ne sais pas si ca va changer quelque chose mais apparemment dans les deux cas le premier passage est bon. Or le point commun entre les deux cas c'est qu'au premier passage dans ta boucle, cmd est vide. Donc peut-être qu'en la réinitialisant à chaque fois ça résoudra ton problème.
    "L'insanité consiste à répéter la même action dans l'espoir d'aboutir à un résultat différent" Albert Einstein
    ----------------------
    T.O.A.O 6-MarViN

  5. #5
    Futur Membre du Club
    Inscrit en
    Septembre 2008
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 14
    Points : 6
    Points
    6
    Par défaut
    Ben pas très concluant ...

    Déjà avec bzero, j'ai une erreur de compil : undefined fonction (alors que j'ai bien string.h d'inclu !)

    J'ai fait un :
    Et le résultat :
    ---------------
    cmds : ping -n 1 123.12.123.10 > NULL
    resultat : 0
    ---------------
    cmds : ping -n 1 4980802.1999633846.1988581918.48 > NULL
    resultat : 1
    ---------------
    cmds : ping -n 1 0.0.2679004.1988581993 > NULL
    resultat : 1
    ---------------
    cmds : ping -n 1 0.0.0.0 > NULL
    resultat : 1
    ---------------
    cmds : ping -n 1 1988583728.88.1988583756.0 > NULL
    resultat : 1
    ---------------
    cmds : ping -n 1 0.2678220.0.0 > NULL
    resultat : 1
    ---------------
    cmds : ping -n 1 0.0.0.0 > NULL
    resultat : 1
    Visiblement, ça ne change rien :-(
    J'ai fait un test entre temps (qui ne résoud rien mais qui peut faire réfléchir !)

    j'ai légèrement modifier mon code pour vérifier si je pingais une ip prédéfini dans un tableau de char genre 192.168.10.1 : et là l'ip ne bouge pas.

    Je me suis dis, bon bah je vais mettre mon ip dans un tableau de char à chaque fois ... donc "ip" reçoit TabOrdi[i].IPOrdi.ip1, TabOrdi[i].IPOrdi.ip2, TabOrdi[i].IPOrdi.ip3, TabOrdi[i].IPOrdi.ip4 (grossièrement) ; et là je fais un ping sur le tableau de char "ip"

    Et bah même problème que précédemment =( l'ip est complêtement modifiée !

    Je ne comprend pas la relation qu'il peut exister entre system () et les int de ma structure :'-(

  6. #6
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Points : 1 750
    Points
    1 750
    Par défaut
    A tout hasard :
    Quel compilateur utilises-tu ? Quelles sont tes options de compilation ? Diminue le niveau d'optimisation (s'il y en a).

  7. #7
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2010
    Messages
    254
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2010
    Messages : 254
    Points : 538
    Points
    538
    Par défaut
    Et quelle plateforme utilise-tu? parce que le bzero pas reconnu ca me choque...
    "L'insanité consiste à répéter la même action dans l'espoir d'aboutir à un résultat différent" Albert Einstein
    ----------------------
    T.O.A.O 6-MarViN

  8. #8
    Membre du Club
    Inscrit en
    Juin 2010
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Juin 2010
    Messages : 7
    Points : 40
    Points
    40
    Par défaut
    On peut voir la fonction chargerFichier ?

  9. #9
    Futur Membre du Club
    Inscrit en
    Septembre 2008
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 14
    Points : 6
    Points
    6
    Par défaut
    Ben j'utilise CodeBlocks avec minGw et les options de compil par défaut ^^

  10. #10
    Futur Membre du Club
    Inscrit en
    Septembre 2008
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 14
    Points : 6
    Points
    6
    Par défaut
    Voilà la fonction :
    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
    Ordi* chargerFichier (char* fichier)
    {
        // Définition des variables
        FILE* fichierCharger = NULL;
        char cheminFichier[500];
        Ordi Tab[100];
        char vid;
        int i = 0;
     
        // Réinitialisation des variables
        strcpy(cheminFichier, "");
        nbreElement = 0;
     
        // initialisation du chemin complet cheminFichier du fichier mis en paramètre
        strcat(cheminFichier, _Path);
        strcat(cheminFichier, fichier);
     
        // Affichage du chemin complet
        printf("%s\n", cheminFichier);
     
        // Chargement du fichier et ouverture en lecture
        if((fichierCharger = fopen (cheminFichier, "r")) != NULL)
        {
            // Tant que le fichier n'est pas terminé
            while(feof(fichierCharger) == 0)
            {
                // Récupération des informations contenues dans le fichier
                fscanf(fichierCharger, "%d.%d.%d.%d;%[^;]s", &Tab[i].IPOrdi.ip1, &Tab[i].IPOrdi.ip2, &Tab[i].IPOrdi.ip3, &Tab[i].IPOrdi.ip4, &Tab[i].NomOrdi);
                fscanf(fichierCharger,"%c",&vid);
                fscanf(fichierCharger,"%s\n", &Tab[i].Telephone);
                i++;
            }
     
            // Définition du nombre d'élément contenu dans le tableau
            nbreElement = i - 1;
     
            // Fermeture du fichierCharger
            fclose(fichierCharger);
     
            // Retour du tableau Tab Ordi*
            return Tab;
        }
        else
        {
            // Sinon afficher une erreur
            printf("erreur !\n");
        }
    }

  11. #11
    Membre du Club
    Inscrit en
    Juin 2010
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Juin 2010
    Messages : 7
    Points : 40
    Points
    40
    Par défaut
    Citation Envoyé par jalekoo Voir le message
    Voilà la fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Ordi* chargerFichier (char* fichier)
    {
        // Définition des variables
        Ordi Tab[100];
    [...]
            return Tab;
        }
    }
    Il faut pas return une variable locale, son adresse est invalide hors de la fonction .
    Fait plutot un malloc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Ordi *Tab
    Tab = malloc(100 * sizeof(*Tab));
    Et return quelque chose en cas d'erreur, null par exemple, sinon tu peux te retrouver avec tout et n'importe quoi dans ta variable qui recupere le retour de la fonction.

  12. #12
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Points : 1 750
    Points
    1 750
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while(feof(fichierCharger) == 0)
    Ce n'est pas la bonne façon de lire un fichier.

  13. #13
    Futur Membre du Club
    Inscrit en
    Septembre 2008
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 14
    Points : 6
    Points
    6
    Par défaut
    Wawou ! Ca marche ! lol ^^

    Alors merci à tous pour votre aide et vos conseils =)

    Malka1986 a trouvé la solution ... En fait, c'était une question de mémoire ! En faisant le malloc, ça marche

    Mais j'ai du mal à comprendre le pourquoi du comment ? (on a jamais vu le malloc en cours, soit disant trop compliqué alors que le prof nous fait commencer la manipulation des classes en C++... J'ai du mal à comprendre sa logique... Bref !)

    Sinon jeroman, ah bon ce n'est pas la bonne façon ? Que me conseil tu ? Tous conseils sont bon à prendre pour améliorer la qualité du programme, et de mes programmes futurs =)

    Merci

  14. #14
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Points : 1 750
    Points
    1 750
    Par défaut
    Citation Envoyé par jalekoo Voir le message
    Sinon jeroman, ah bon ce n'est pas la bonne façon ? Que me conseil tu ? Tous conseils sont bon à prendre pour améliorer la qualité du programme, et de mes programmes futurs =)

    Merci
    Extrait de la FAQ :
    Contrairement à une pratique trop souvent rencontrée, la fonction feof() ne sert pas à détecter la fin d'un fichier mais, lorsqu'une lecture a échoué, à savoir si cet échec est du à la rencontre de la fin de fichier.

    La bonne pratique pour lire intégralement un fichier consiste donc à parcourir le fichier tant qu'aucune erreur de lecture n'est remontée et d'utiliser ferror et feof pour déterminer, suite à une erreur, la cause de cette erreur.
    Le mieux, c'est d'utiliser la fonction fgets, de tester si elle ne renvoie pas NULL. Ensuite, tu peux troquer tes fscanf par des sscanf.

    EDIT:

    Malka1986 a trouvé la solution ... En fait, c'était une question de mémoire ! En faisant le malloc, ça marche

    Mais j'ai du mal à comprendre le pourquoi du comment ? (on a jamais vu le malloc en cours, soit disant trop compliqué alors que le prof nous fait commencer la manipulation des classes en C++... J'ai du mal à comprendre sa logique... Bref !)
    Les variables (ou tableaux) locales à une fonction sont stockés sur la pile. Du coup, lorsqu'on quitte la fonction, les données peuvent à tout moment être écrasées par autre chose.

  15. #15
    Futur Membre du Club
    Inscrit en
    Septembre 2008
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 14
    Points : 6
    Points
    6
    Par défaut
    Ok ! Ca marche =)

    Bonne journée à tous et encore merci !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. fonction system et probleme d'arobase
    Par yerome dans le forum Langage
    Réponses: 3
    Dernier message: 08/07/2005, 16h53
  2. Réponses: 10
    Dernier message: 08/02/2005, 16h04
  3. Réponses: 1
    Dernier message: 20/08/2004, 09h16
  4. Réponses: 2
    Dernier message: 30/03/2004, 11h31
  5. Réponses: 13
    Dernier message: 20/03/2003, 08h11

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