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 :

Execution différente sous Windows et UNIX


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    129
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 129
    Par défaut Execution différente sous Windows et UNIX
    Bonjour,

    Je viens vous faire part d'un problème pour le moins étonnant.
    J'ai un programme qui permet de faire des calculs et de retrouver le signe astrologique chinois.
    Sous les systèmes basé sur Linux (testé sous Ubuntu) et OSX (leopard et Snow Leopard) tout fonctionne comme prévu.

    Mais sous windows ce n'est pas le cas. Le programme fonctionne dans un sens mais pas dans l'autre.

    Si vous entrez :

    Quel est le prenom de la personne :
    Jack

    Quel est son annee de naissance?
    1900

    Voulez vous rentrer une autre personne (o pour oui, n pour non)?
    o

    Quel est le prenom de la personne :
    Bob

    Quel est son annee de naissance?
    1988

    Vous Obtenez qu'ils sont compatibles. Que vous entriez dans un sens ou dans l'autre rien n'y change et c'est marche sous Linux et OSX.... Mais sous Windows ce n'est pas le cas. Par défaut, la première date entrée ne s'enregistre pas.

    Ci dessous les screenshot :

    ne fonctionne pas sous Windows dans un sens



    OK dans l'autre sens


    OK dans les deux sens sous OSX et Linux



    Merci d'avance.... je ne comprends pas.
    Je compile sous Windows sous Parallels avec DevC++ et MinGW32 3.4.2

    Voici le 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
    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
    #include <stdio.h>
     
    #define TAB_LENGTH 100
    #define NAME_LENGTH 30
     
    int getSigne(int annee)
    {
        return annee % 12;
    }
     
    char isCompatible(int annee1, int annee2)
    {
        int compatibilites[] = {  4, //à la case 0, on met la valeur 4 pour associer singe(0) à rat(4)
                                    -1, //à la case 1 pas de compatibilité pour coq(1)
                                    -1,
                                    -1,
                                    8,
                                    4,
                                    2,
                                    3,
                                    -1,
                                    1,
                                    2,
                                    3
                                }; 
        int signe1 = getSigne(annee1), signe2 = getSigne(annee2);
        printf("annee : %d = %d et annee : %d = %d\n",annee1,signe1,annee2,signe2);
        return ( compatibilites[signe1] == signe2 || compatibilites[signe2] == signe1);
    }    
    int main(void)
    {
        char* signes[] = { "singe",     //0
                                "coq",       //1
                                "chien",     //2
                                "porc",      //3
                                "rat",       //4
                                "buffle",    //5
                                "tigre",     //6
                                "lièvre",    //7
                                "dragon",    //8
                                "serpent",   //9
                                "cheval",    //10
                                "chevre"     //11
        };
        char prenoms[TAB_LENGTH][NAME_LENGTH];
        int  annees[TAB_LENGTH];
        char next = 'o';
        int i = 0;
        while (next == 'o' && i < TAB_LENGTH)
        {
            int j=0;
            printf("Quel est le prenom de la personne? ");
            scanf("%s", &prenoms[i]);
            printf("\nQuel est son annee de naissance? ");
            scanf("%d", &annees[i]);
            printf("Merci. %s est de signe %s.\n", prenoms[i], signes[getSigne(annees[i])]);
     
            for (j = 0; j < i; j++)
            {
            printf("annee : %d et annee : %d\n",annees[i],annees[j]);
                if (isCompatible(annees[i], annees[j]))
                {
                    printf("%s est compatible avec %s.\n", prenoms[i], prenoms[j]);
                }
            }        
     
            printf("\nVoulez vous rentrer une autre personne (o pour oui, n pour non)? ");
            scanf("%s", &next);
            i++;
        }
        return 1;
    }
    Si vous pouviez m'éclairer ? Merci d'avance à tous !

  2. #2
    Invité(e)
    Invité(e)
    Par défaut
    Bonjour,

    Je pense que le problème vient de la variable next : quand le scanf rempli cette variable, il y met "o\0" et non 'o' : il manque de la place dans next pour stocker la réponse complète, le scnaf déborde et écrit n'import où : dans annees[0] en l'occurrence.

    Solution : remplacer next :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    char next[2] = "o";
    ...
    while (next[0] == 'o' && i < TAB_LENGTH)
    ...
    scanf("%s", next);
    ...
    Au passage, scanf n'est pas forcément la meilleure fonction du monde pour ce genre d'entrées, un peu de lecture : http://emmanuel-delahaye.developpez....ees-solides-c/.

    De plus, le remplissage des nmos peut se faire plus simplement comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    scanf("%s", prenoms[i]);
    Dernière modification par Deepin ; 25/07/2011 à 09h50.

  3. #3
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Il y a une erreur grave ici :
    Lorsqu'on rentre 1 caractère, au moins deux sont stockés (à cause du '\0'). Or seul un char est prévu pour le stockage. Le deuxième char va donc écraser ce qui se trouve derrière next ce qui est dépendant du compilateur.

    Une erreur de type (sans gravité dans ce contexte d'utilisation) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    scanf("%s", prenoms[i]); // pas de &

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    129
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 129
    Par défaut
    Merci.
    J'avais les yeux dans le bousin 0_O
    Je ne cherchais pas du tout ici ! oui pour scanf je sais bien... mais malheureusement, nous avons décidé de commencer avec cela.
    Une erreur de ce type permet néanmoins de montrer les limites

    Merci pour votre réponse.

    En revanche quel type de vérification font les compilateur sous Linux et Osx ? gcc 4.2.1

    Encore merci !

  5. #5
    Invité(e)
    Invité(e)
    Par défaut
    Citation Envoyé par SpongeBob Voir le message
    En revanche quel type de vérification font les compilateur sous Linux et Osx ? gcc 4.2.1
    Il n'y a pas de vérification en plus.

    La différence qui existe entre les exécutables est que chaque variable ne sera pas au même emplacement mémoire.

    Ce qui veux dire que le problème existe aussi dans la version UNIX mais que les conséquences sont moins graves.

    Tu peux ajouter ceci à la fin de ton programme pour t'en rendre compte :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    printf("prenom est en %p\n", prenoms);
    printf("annees est en %p\n", annees);
    printf("next est en %p\n", &next); /* ou next sans '&' si de type char[]*/
    printf("i est en %p\n", i);

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

Discussions similaires

  1. Reports sous Windows et UNIX
    Par karamasov59 dans le forum Reports
    Réponses: 5
    Dernier message: 23/11/2007, 10h02
  2. Exécution de JCL sous Windows ou Unix
    Par al1_24 dans le forum JCL - SORT
    Réponses: 3
    Dernier message: 23/07/2007, 20h33
  3. Problème d'execution c++ sous windows
    Par maxetime dans le forum Windows
    Réponses: 5
    Dernier message: 06/10/2006, 14h39
  4. Code compilable sous Windows et Unix
    Par xzed dans le forum C
    Réponses: 9
    Dernier message: 16/05/2006, 16h06
  5. Norme POSIX sous Windows et Unix
    Par Franck.H dans le forum Langages de programmation
    Réponses: 9
    Dernier message: 10/10/2005, 20h46

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