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 :

problème d'erreur au run


Sujet :

C

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 14
    Par défaut problème d'erreur au run
    Je travaille sur un programme qui travaille sur cette suite logique :
    1
    11
    21
    1211
    .....
    Bref une suite assez simple où la ligne suivante renseigne sur la quantité d'un certain nombre en les prenants à la suite (ex : 21=> il y a un 2 et un 1 donc on écrit 1211)

    Donc j'ai conçu ce programme
    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
    #include <stdio.h>
    void main(void)
    {
       char T[100][255];
       long i,k,j;
       T[0][0]=49;
       for (i=1;i<=253;i++) T[0][i]=48;
       k=0;
       i=0;
       for (j=0;j<=98;j++)
          {
              while (T[j][i]!=48)
                 {
                     if (T[j][i]!=T[j][i+1])
                         {
                     	     T[j+1][k]=49;
                     	     T[j+1][k+1]=T[j][i];
                     	     i=i+1;
                     	     k=k+2;
                     	 }
                     else if (T[j][i]==T[j][i+1]&&T[j][i]!=T[j][i+2])
                     	 {
                     	     T[j+1][k]=50;
                     	     T[j+1][k+1]=T[j][i];
                     	     i=i+2;
                     	     k=k+2;
                     	 }
                     else 
                         {
                     	     T[j+1][k]=51;
                     	     T[j+1][k+1]=T[j][i];
                     	     i=i+3;
                     	     k=k+2;
                     	 }
                 }
              i=0;
              for (i=k;i<=253;i++) T[j+1][k]=48;
              k=0;
          }
       for (j=0;j<=99;j++) 
          {
              for (i=0;i<=253;i++)
                  {
                      while (T[j][i+1]!=48) printf("%c",T[j][i]);
                  }
              printf("\n");
          }
       getchar();
    }
    mais à chaque fois lorsque je compile, il ne m'affiche aucune erreur mais lors du run, j'ai ce message

    NO-FATAL RUN-TIME ERROR
    "défi.c", line 12, col 18, thread is 0x00000B8C
    Local "T" is referenced before being initialized

    Mais pas moyen de trouver une solution, pouvez m'aider s'il vous plait?
    Merci d'avance de vos réponses!

  2. #2
    Membre émérite Avatar de homeostasie
    Homme Profil pro
    Inscrit en
    Mai 2005
    Messages
    939
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 939
    Par défaut
    Bonjour et bienvenue,

    Perso, je pense fortement à un débordement mémoire. A savoir où, c'est autre chose!

    Va falloir bien débugger et aussi rendre ton code plus lisible, mettre des commentaires pour expliquer ce que tu fais.

    Le mieux serait que tu fasses au préalable un travail de conception en mettant au point ton algorithme, ensuite tu codes.

  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
    Bonjour et bienvenue
    il semble qu'il y ait une erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     ...          
     i=0;
     for (i=k;i<=253;i++) T[j+1][k]=48;
     k=0;
    Plutôt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     ...          
    
     for (i=k;i<=253;i++) T[j+1][i]=48;
     i=0;
     k=0;
    De plus, au dela de j = 18 environ, le tableau de 255 char sera trop petit pour contenir le résultat. Il faut modifier le test d'arrêt de la boucle for en fonction de la capacité du tableau

  4. #4
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par zinjulio Voir le message
    Donc j'ai conçu ce programme
    J'ai un peu instrumenté le code. Ca a craqué assez vite...
    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
     
    #include <stdio.h>
    #include <assert.h>
     
    int main (void)
    {
       char T[100][255];
       size_t i, k, j;
       T[0][0] = 49;
       for (i = 1; i <= 253; i++)
       {
          assert (i < sizeof *T / sizeof **T);
          T[0][i] = 48;
       }
       k = 0;
       i = 0;
       for (j = 0; j <= 98; j++)
       {
          while (T[j][i] != 48)
          {
             if (T[j][i] != T[j][i + 1])
             {
                assert (j + 1 < sizeof T / sizeof *T);
                assert (j < sizeof T / sizeof *T);
                assert (k + 1 < sizeof *T / sizeof **T);
     
                T[j + 1][k] = 49;
                T[j + 1][k + 1] = T[j][i];
                i = i + 1;
                k = k + 2;
             }
             else if (T[j][i] == T[j][i + 1] && T[j][i] != T[j][i + 2])
             {
                T[j + 1][k] = 50;
                T[j + 1][k + 1] = T[j][i];
                i = i + 2;
                k = k + 2;
             }
             else
             {
                T[j + 1][k] = 51;
                T[j + 1][k + 1] = T[j][i];
                i = i + 3;
                k = k + 2;
             }
          }
          i = 0;
          for (i = k; i <= 253; i++)
             T[j + 1][k] = 48;
          k = 0;
       }
       for (j = 0; j <= 99; j++)
       {
          for (i = 0; i <= 253; i++)
          {
             while (T[j][i + 1] != 48)
                printf ("%c", T[j][i]);
          }
          printf ("\n");
       }
       return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Assertion failed: k + 1 < sizeof *T / sizeof **T, file main.c, line 24
     
    This application has requested the Runtime to terminate it in an unusual way.
    Please contact the application's support team for more information.
     
    Press ENTER to continue.
    Débordement, de tableau, comportement indéfini...

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 52
    Par défaut
    Une solution simple serait peut être de faire une fonction prenant en paramètre une chaîne a analyser et retournant un pointeur sur char contenant la chaîne résultante.

    Dans la fonction,

    - Tu alloue une chaîne de longueur égale a deux fois celle à analyser + 1 pour le zéro terminal (Dans le pire des cas, si tous les caractères sont différents, ta ligne de sortie est deux fois plus longue que la ligne d'entrée).

    - Tu parcours avec un pointeur la chaîne d'entrée jusqu'à la fin.
    A chaque caractère, s'il est égal au précédent, tu incrémente un compteur
    Sinon, tu ajoute ton compteur et le caractère précédent à la fin de ta chaîne de sortie.

    Tu n'a plus qu'a rappeler ta chaîne autant de fois que tu le désire avec en entrée la chaine retournée par l'appel précédent.

    Ne pas oublier de libérer les chaines allouées en fin de programme.

    Bon courage

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 14
    Par défaut
    J'ai commencé à modifier mon programme et voici ce que cela donne :
    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
    #include <stdio.h>
    char calcul(char T[]);
    void main(void)
    {
       char T[2];
       int i;
       T[0]=49;
       printf("%c",T[0]);
       for (i=1;i<=99;i++) 
       {
           printf("%c",calcul(T[]));
           T[]=calcul(T);
       getchar();
    }
     
    char calcul(char T[])
    {
       int i=0,j,k=1,l=0;
       while (T[i]!==00) i++;
       char U[(i*2)+1];
       for (j=0;j<=i*2;j++)
          {
              if (T[j]==T[j+1]) k++;
              else
                   {
                       U[l]=k+48;
                       U[l+1]=T[j];
                       l=l+2;
                       k=1;
                   }
       return U[];
    }
    La fonction calcul permet de calculer la ligne suivante à partir de la précèdente.
    Je me doute que ce programme comporte des erreurs j'ai donc plusieurs questions pour vous :
    -Comment on appelle une fonction qui renvoie comme résultat un tableau? j'ai lu la faq mais je n'ai pas tout compris!
    -Aussi j'aimerais savoir comment fait-on un tableau à itération variable? car dans la fonction calcul le tableau U doit être au maximun deux fois plus grand que le tableau T mais je ne sais pas exactement comment l'on traduit cela en language c!

    merci de vos réponses

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 52
    Par défaut
    Il y a du pain sur la planche,

    -Comment on appelle une fonction qui renvoie comme résultat un tableau? j'ai lu la faq mais je n'ai pas tout compris!
    Actuellement ta fonction calcul retourne un caractère et non un pointeur sur une chaîne de caractère. Pour retourner un pointeur, ta fonction devrait plutôt ressemble a ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    char *calcul(char *T)
    Pour connaître la taille d'une chaîne de caractères, utilise la fonction strlen().

    Dans la construction de ta chaîne, pour plus de clarté, au lieu d'écrire
    écris donc
    pour faire ce que tu appelles un tableau à itération variable, utilise malloc().
    Donc pour réserver une chaîne de longueur double de celle passée en paramètre, ta fonction calcul devient :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    char *calcul(char *LigneIn)
    {
    char *Retour;       // Chaine retournee
    Retour=malloc(2*strlen(LigneIn)+1);
    if(Retour!=NULL)
      {
      //Remplir ici la chaîne Retour
      }
    return(Retour);
    Tu n'as plus qu'a remplir correctement ta chaîne Retour et a appeler autant de fois que tu veux ta fonction depuis un main() similaire a celui ci.



    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
     
    #include <stdio.h>
    #include <stdlib.h>
     
    // Nombre de chaines a generer
    #define NB_CHAINES 10
     
    int main(void)
    {
    char *Tmp[NB_CHAINES];  // Declare NB_CHAINES pointeurs sur char
    int ii;
     
    // alloue et initialise la premiere chaine
    Tmp[0]=malloc(2);
    strcpy(Tmp[0],"1");
     
    // Appelle la fonction de création d'une chaîne a partir de la précédente
    for(ii=1;ii<NB_CHAINES;ii++)
      {
      Tmp[ii]=Calcul(Tmp[ii-1]);
      printf("Tmp[%d]=%s\n",ii,Tmp[ii]);
      }
     
    // Libére les chaines allouées
    for(ii=0;ii<NB_CHAINES;ii++)
      free(Tmp[ii]);
     
    return(0);
    }
    La balle est dans ton camps.

  8. #8
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Fred83 Voir le message
    Pour connaître la taille d'une chaîne de caractères, utilise la fonction strlen().
    Pour être précis, strlen(), comme son nom l'indique, donne la longueur de la chaine (length) sans le 0 final...

  9. #9
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 14
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    // Libére les chaines allouées
    for(ii=0;ii<NB_CHAINES;ii++)
      free(Tmp[ii]);
    Pourquoi faut-il libérer les chaînes allouées? (Je n'ai pas encore fait cela en cours donc une explication précise me serait très utile ne serait-ce rien que pour ma culture personnelle)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    char *calcul(char *LigneIn)
    {
    char *Retour;       // Chaine retournee
    Retour=malloc(2*strlen(LigneIn)+1);
    if(Retour!=NULL)
      {
      //Remplir ici la chaîne Retour
      }
    return(Retour);
    Aussi je ne comprend pas très bien le rôle de la fonction malloc! Pouvez vous l'expliquer?

  10. #10
    Membre éclairé
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 52
    Par défaut
    Pourquoi faut-il libérer les chaînes allouées? (Je n'ai pas encore fait cela en cours donc une explication précise me serait très utile ne serait-ce rien que pour ma culture personnelle)
    Pour rendre à César, ce qui appartient a César.
    simplement, avec Malloc tu demandes au système de te prêter une zone mémoire. Avec free, tu la lui rend.

    Aussi je ne comprend pas très bien le rôle de la fonction malloc! Pouvez vous l'expliquer?
    Malloc expliqué en français dans le texte
    http://fr.wikipedia.org/wiki/Malloc

    Dans l'exemple, tu as au maximum besoin d'une chaîne de longueur double de la chaine d'entrée.
    strlen(LigneIn) te donne la longueur utile (sans le 0 terminal) de ta chaîne d'entrée.
    2*strlen(LigneIn)+1 correspond a la longueur a réserver pour une chaîne de longueur double + 1 pour le zéro terminal.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Retour=malloc(2*strlen(LigneIn)+1);
    Pour ton problème, la réservation mémoire est indispensable et sa restitution aussi. Tu dois t'attendre a des chaînes qui deviennent rapidement très longue.
    ce qui explique tes plantages du début.
    Pour info, en laissant tourner un peu ton programme tu trouvera une chaîne de 5808 caractères au 31 ème passage et de plus de 63000 au 40ème.

    Bon courage.

  11. #11
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 14
    Par défaut
    Moi je dois au maximun aller au 99ème passage, cela ne posera pas de problème?

  12. #12
    Membre éclairé
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 52
    Par défaut
    Tu verras bien.

    Pour ton problème, pour construire une chaîne tu n'as besoin que de la précédente, donc tu peut travailler avec uniquement deux pointeurs.

    Commence par écrire et valider ta fonction de calcul.

    au 48 ème passage, sauf erreur de ma part la chaîne résultante fait plus de 680000 caractères alors au 100 ème ?.

  13. #13
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 14
    Par défaut
    Voilà mon programme terminé mais il reste plein d'erreur :!

    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
    #include <ansi_c.h>
    #include <stdio.h>
    void main(void)
     
    {
    int NB_CHAINE=0;
    printf("Veuillez saisir la ligne dont vous voulez la valeur :");
    scanf("%d",NB_CHAINE);
    while (NB_CHAINE<0||NB_CHAINE>99)
       {
           printf("Erreur de saisie, recommencez :");
           scanf("%d",NB_CHAINE); 
    char *TAB[NB_CHAINE];  // Declare NB_CHAINE pointeurs sur char
    int ii;
     
    // alloue et initialise la premiere chaine
    TAB[0]=malloc(2);
    strcpy(TAB[0],"1");
     
    // Appelle la fonction de création d'une chaîne a partir de la précédente
    for(ii=1;ii<NB_CHAINE;ii++)
      {
      TAB[ii]=Calcul(TAB[ii-1]);
      printf("TAB[%d]=%s\n",ii,TAB[ii]);
      }
     
    // Libére les chaines allouées
    for(ii=0;ii<NB_CHAINE;ii++)
      free(TAB[ii]);
     
    }
     
    char *calcul(char *LigneIn)
    {
    char *Retour;       // Chaine retournee
    i=0;
    k=0;
    Retour=malloc(2*strlen(LigneIn)+1);
    while (LigneIn[i]!=NULL)
      {
        if (LigneIn[i]!=LigneIn[i+1])
            {
                Retour[K]='1';
                Retour[K+1]=LigneIn[i];
                k=k+2;
                i++;
            }
        else if (LigneIn[i]==LigneIn[i+1]&&LigneIn[i]!=LigneIn[i+2])
                 {
                     Retour[K]='2';
                     Retour[K+1]=LigneIn[i];
                     k=k+2;
                     i=i+2;
                 }
             else
                  {   
                     Retour[K]='3';
                     Retour[K+1]=LigneIn[i];
                     k=k+2;
                     i=i+3;
                  }
      }
    return(Retour);
    Par exemple ici
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char *TAB[NB_CHAINE];  // Declare NB_CHAINE pointeurs sur char
    il me marque
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Illegal statement termination
    Pourquoi?

  14. #14
    Membre éclairé
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 52
    Par défaut
    Tu ne peut pas déclarer un tableau dont la dimension n'est pas connue au moment de la compilation.
    Dans ton programme NB_CHAINE est une variable, dans mon exemple c'est une constante.

    Ta fonction calcul risque de ne pas calculer.

    while (LigneIn[i]!=NULL)
    {
    ....
    else if (LigneIn[i]==LigneIn[i+1]&&LigneIn[i]!=LigneIn[i+2])
    {
    Lorsque LigneIn[i] va pointer sur l'avant dernier caractère, LigneIn[i+2] sera t'il valable ?.

  15. #15
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 14
    Par défaut
    Voici mon programme modifié a l'aide de vos conseils :
    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
    #include <ansi_c.h>
    #include <stdio.h>
    char *Calcul(char *LigneIn);
    void main(void)
    #define NB_CHAINE 99
    {
    char *TAB[NB_CHAINE];  // Declare NB_CHAINE pointeurs sur char
    int ii,n;
    printf("Veuillez saisir la ligne que vous voulez afficher :");
    scanf("%d",&n);
    while (n<1||n>99)
       {
           printf("Erreur de saisie, recommencez :");
           scanf("%d",&n);
       }
     
    // alloue et initialise la premiere chaine
    TAB[0]=malloc(2);
    strcpy(TAB[0],"1");
     
    // Appelle la fonction de création d'une chaîne a partir de la précédente
    for(ii=1;ii<NB_CHAINE-1;ii++)
      {
      TAB[ii]=Calcul(TAB[ii-1]);
      }
    printf("%c",TAB[n]);
     
     
    // Libére les chaines allouées
    for(ii=0;ii<NB_CHAINE;ii++)
      free(TAB[ii]);
    getchar(); 
    }
     
    char *Calcul(char *LigneIn)
    {
    char *Retour;       // Chaine retournee
    int i,K;
    i=0;
    K=0;
    Retour=malloc(2*strlen(LigneIn)+1);
    while (LigneIn[i]!=NULL)
      {
        if (LigneIn[i]!=LigneIn[i+1])
            {
                Retour[K]='1';
                Retour[K+1]=LigneIn[i];
                K=K+2;
                i++;
            }
        else if (LigneIn[i]!=LigneIn[i+2])
                 {
                     Retour[K]='2';
                     Retour[K+1]=LigneIn[i];
                     K=K+2;
                     i=i+2;
                 }
             else
                  {   
                     Retour[K]='3';
                     Retour[K+1]=LigneIn[i];
                     K=K+2;
                     i=i+3;
                  }
      }
    return(Retour);
    }
    Quand je lance, il me marque une erreur du style "general protection fault"!!
    D'où cela peut-il venir?

  16. #16
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par zinjulio Voir le message
    Voici mon programme modifié a l'aide de vos conseils :
    <...>
    Quand je lance, il me marque une erreur du style "general protection fault"!!
    D'où cela peut-il venir?
    Ton code commenté et corrigé sur le plan du codage.
    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
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
     
    /* -ed- Pas du C standard
    #include <ansi_c.h>
     
    Ajoutes : */
    #include <string.h>
    #include <stdlib.h>
     
    #include <stdio.h>
     
    /* -ed-
    char *Calcul(char *LigneIn);
     
    inutile de separer le prototype ici.
    Il suffit de definir avant d'utiliser. */
    char *Calcul (char *LigneIn)
    {
       char *Retour;                // Chaine retournee
       int i, K;
       i = 0;
       K = 0;
       Retour = malloc (2 * strlen (LigneIn) + 1);
     
    /* -ed-
    while (LigneIn[i]!=NULL)
     
    Ceci n'a aucnu sens. LigneIn[i] et un char et NULL est un pointeur.
    Tu veux peut etre  :
     
    */
       while (LigneIn[i] != 0)
       {
          if (LigneIn[i] != LigneIn[i + 1])
          {
             Retour[K] = '1';
             Retour[K + 1] = LigneIn[i];
             K = K + 2;
             i++;
          }
          else if (LigneIn[i] != LigneIn[i + 2])
          {
             Retour[K] = '2';
             Retour[K + 1] = LigneIn[i];
             K = K + 2;
             i = i + 2;
          }
          else
          {
             Retour[K] = '3';
             Retour[K + 1] = LigneIn[i];
             K = K + 2;
             i = i + 3;
          }
       }
     
       /* -ed- parentheses inutiles */
       return (Retour);
    }
     
    /* -ed- main() retourne int. Toujours.
    void main(void)
    */
    int main (void)
    #define NB_CHAINE 99
    {
       char *TAB[NB_CHAINE];        // Declare NB_CHAINE pointeurs sur char
       int ii, n;
       printf ("Veuillez saisir la ligne que vous voulez afficher :");
       scanf ("%d", &n);
       while (n < 1 || n > 99)
       {
          printf ("Erreur de saisie, recommencez :");
          scanf ("%d", &n);
       }
     
    // alloue et initialise la premiere chaine
       TAB[0] = malloc (2);
       strcpy (TAB[0], "1");
     
    // Appelle la fonction de création d'une chaîne a partir de la précédente
       for (ii = 1; ii < NB_CHAINE - 1; ii++)
       {
          TAB[ii] = Calcul (TAB[ii - 1]);
       }
       /* -ed-
       printf ("%c", TAB[n]);
     
       Ceci est incoherent. "%c" attend un int (caractere)
       et tu lui passe l'adresse d'un char...
     
       Tu veux peut etre : */
       printf ("%s", TAB[n]);
     
    // Libére les chaines allouées
       for (ii = 0; ii < NB_CHAINE; ii++)
          free (TAB[ii]);
       getchar ();
     
       /* -ed- parce que main() retourne un int. 0 signifie OK. */
       return 0;
    }
    Par contre, son comportement est instable (boucle infinie).

    Il y a un problème de conception (algorithme erroné).

  17. #17
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 14
    Par défaut
    Voilà mon programme désormais :
    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
    #include <ansi_c.h>
    #include <string.h>
    #include <stdlib.h>
    #include <stdio.h>
    char *Calcul(char *LigneIn);
     
    char *Calcul (char *LigneIn)
    {
       char *Retour;                
       int i, K;
       i = 0;
       K = 0;
       Retour = malloc (2 * strlen (LigneIn) + 1);
       while (LigneIn[i] != 0)
       {
          if (LigneIn[i] != LigneIn[i + 1])
          {
             Retour[K] = '1';
             Retour[K + 1] = LigneIn[i];
             K = K + 2;
             i++;
          }
          else if (LigneIn[i] != LigneIn[i + 2])
          {
             Retour[K] = '2';
             Retour[K + 1] = LigneIn[i];
             K = K + 2;
             i = i + 2;
          }
          else
          {
             Retour[K] = '3';
             Retour[K + 1] = LigneIn[i];
             K = K + 2;
             i = i + 3;
          }
       }
       return Retour;
    }
     
    int main (void)
    #define NB_CHAINE 99
    {
       char *TAB[NB_CHAINE];        
       int ii, n, c;
       printf ("Veuillez saisir la ligne que vous voulez afficher :");
       scanf ("%d", &n);
       while (n < 1 || n > 99)
       {
          printf ("Erreur de saisie, recommencez :");
          scanf ("%d", &n);
       }
     
       TAB[0] = malloc (2);
       strcpy (TAB[0], "1");
     
       for (ii = 1; ii <= n; ii++)
       {
          TAB[ii] = Calcul (TAB[ii - 1]);
       }
       printf ("%s", TAB[n]);
       printf("voilà le résultat!!!");
       getchar();
       for (ii = 0; ii <= n ; ii++)
          free (TAB[ii]);
       return 0;
    }
    Lorsque je lance le programme il me met cette erreur : "missing terminating null in string argument"! A quoi est ce du?
    De plus, je n'arrive pas à trouver d'où peux venir la boucle infini! :!

  18. #18
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par zinjulio Voir le message
    Voilà mon programme désormais :

    Lorsque je lance le programme il me met cette erreur : "missing terminating null in string argument"! A quoi est ce du?
    De plus, je n'arrive pas à trouver d'où peux venir la boucle infini! :!
    Genre tétu, hein ?
    n'existe pas en C standard. Soit tu donnes le contenu, soit tu le retires.

    Il semble que l'exécution signale une absence de 0 dans une chaine, ce qui est plutôt étonnant, car ça suppose des moyens 'magiques' (cachés) pour tester la taille des tableaux et des zones allouées. Quel est ton compilateur ?

    La boucle infinie provient de ce que la saisie demande 'une ligne'. Moi, bêtement, je tape "hello world"<enter> et évidemment, comme l'erreur de scanf() n'est pas traitée, ça part en vrille...

    Déjà, tu devrais plutôt demander un 'numéro de ligne', ça limiterait les erreurs de saisies...

    De plus je t'ai déjà expliqué que les indices valides d'un tableau allaient de 0 à N-1 et je vois encore des
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for (ii = 1; ii <= n; ii++)

  19. #19
    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
    Citation Envoyé par zinjulio Voir le message
    Voilà mon programme désormais :
    Lorsque je lance le programme il me met cette erreur : "missing terminating null in string argument"! A quoi est ce du?
    La chaine retournée par Calcul n'est pas terminée par un zéro comme doivent l'être les chaines en C
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    char *Calcul (char *LigneIn)
    {
    ....
    Retour[K] = 0;   
    return Retour;
    }
    Il faut absolument tester dans Calcul le retour de malloc, les demandes d'allocation vont devenir très copieuses. Par exemple pour n=50, tu dois arriver à plus d'un million de caractères dans la chaîne sauf erreur. Alors pour 100....

  20. #20
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 14
    Par défaut
    J'ai retiré le #include <ansi_c.h> et mis les bons indices dans le for!!

    Dans le code que tu as posté, il n'y a pas d'erreur comme tu le signales (manque une " dans une chaine de caractères).
    Pou l'erreur, elle est peut être du à un e mauvaise configuration de labWindows CVI! Il me semble par mégarde avoir changer une option mais je ne sais pas comment y remédier! Le fait étant que cela marque tout le temps l'erreur!

    La boucle infinie provient de ce que la saisie demande 'une ligne'. Moi, bêtement, je tape "hello world"<enter> et évidemment, comme l'erreur de scanf() n'est pas traitée, ça part en vrille...

    Déjà, tu devrais plutôt demander un 'numéro de ligne', ça limiterait les erreurs de saisies...
    Je n'ai pas très bien saisi ta phrase! Tu parles des pointeurs?

Discussions similaires

  1. [EasyPHP] Problème EasyPHP erreur 404
    Par caledonie dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 1
    Dernier message: 13/12/2006, 18h00
  2. Réponses: 2
    Dernier message: 22/05/2006, 10h59
  3. Problème ListBox 'Erreur 2176'
    Par emeraudes dans le forum IHM
    Réponses: 5
    Dernier message: 19/05/2006, 17h04

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