Partage
  • Partager sur Facebook
  • Partager sur Twitter

Problème char et char[]

    29 septembre 2021 à 15:31:43

    Bonjour, 

    je cherche à stocker le contenu d'un char, dans un tableau où chaque caractère aurait sa propre "case".

    le problème est que le code que j'ai créé ne fonctionne pas:

    char str;
    while (!feof(file))
    {
                
                fread(&str, sizeof(char), 1, file);
                printf("%02x", (unsigned char)str);
    }

    jusque là aucune soucis quand j'affiche str j'obtiens le bon résultat.

    le problème est lorsque je cherche à changer str (qui est de type "lorem ipsum..." en tableau de caractère où chaque caractère aurait sa case comme ceci ("l","o","r","e","m"," ","i","p","s","u","m");

    pour cela je change 

    char str;
    //en
    char str[]={0};

    Mais là je n'obtiens pas du tout le résultat escompté.

     Des idées ?

    Cordialement.


    -
    Edité par Nhayku 29 septembre 2021 à 15:35:14

    • Partager sur Facebook
    • Partager sur Twitter
      29 septembre 2021 à 15:50:21

      char str[]={0};

      déclare un tableau d'une seule case initialisé à 0 !

      Une seule case veux dire que tu ne pourras pas y mettre grand chose !

      Tu n'as pas vu les tableaux dans ton cours ?

      • Partager sur Facebook
      • Partager sur Twitter
      ...
        29 septembre 2021 à 16:42:03

        > le problème est lorsque je cherche à changer str (qui est de type "lorem ipsum..." en tableau de caractère où chaque caractère aurait sa case comme ceci ("l","o","r","e","m"," ","i","p","s","u","m");

        Bon, les mots ont un sens, surtout dans un domaine technique comme la programmation.

        • str n'est pas de type "lorem ipsum". str est déclaré de type char, point.
        • Si on veut réserver un espace nommé str représentant un tableau de caractères, pas de problème, avec la déclaration
        // oups, pas :  char[100] str;
        char str[100];
        
        on pourra y mettre une chaine de 99 caractères, parce qu'il faut aussi stocker l'octet qui marque la fin de la chaine.
        Au passage, pour y copier "lorem ipsum", il faudra passer une fonction de bibliothèque
        strcpy(str, "lorem ipsum");
        et non, str = "lorem ipsum"; ça ne marchera pas.
        Une alternative, déclarer tout en initialisant
        char str[] = "lorem ipsum";
        
        ou, en se faisant bien suer
        char str[] = { 'l', 'o', 'r', ..... 'm', '\0'};

         Apostrophes pour les caractères, guillemets pour les chaines.

        -
        Edité par michelbillaud 29 septembre 2021 à 17:55:11

        • Partager sur Facebook
        • Partager sur Twitter
          29 septembre 2021 à 17:25:41

          michelbillaud a écrit:

          • Si on veut réserver un espace nommé str représentant un tableau de caractères, pas de problème, avec la déclaration
          char[100] str;
          
              char str[100];



          • Partager sur Facebook
          • Partager sur Twitter
            29 septembre 2021 à 17:55:27

            c'est le java qui ressort :-)

            • Partager sur Facebook
            • Partager sur Twitter
              29 septembre 2021 à 18:10:24

              C'est ce que j'ai essayé hier mais sans succès:

              char str_cpy[1000];
              strcpy(str_cpy, str);

              j'obtiens une erreur lors de l'exécution:

              Violation d'accès lors de la lecture de l'emplacement 0x00000042.
              

              Alors je change donc ma déclaration de str avec char str[1000].

              Mais là, ce qui s'affiche n'est pas correct au sens où ce n'est pas le même (et correct) résultat. J'obtiens une suite de 68 alors que je devrais obtenir le code du fichier en question.

              en revanche char str; me donne le bon résultat mais impossible de le copier dans un char str_cpy[1000] pour le découper ensuite.


              -
              Edité par Nhayku 29 septembre 2021 à 18:14:50

              • Partager sur Facebook
              • Partager sur Twitter
                29 septembre 2021 à 18:28:46

                Il faudrait peut-être poster ton code au complet, ou du moins une version où le problème se reproduit.
                • Partager sur Facebook
                • Partager sur Twitter

                Le Tout est souvent plus grand que la somme de ses parties.

                  29 septembre 2021 à 18:39:47

                  Salut Nhayku,

                  Une variable char c; permet de stocker un seul char à la fois.

                  en faisant :

                  char str;
                  while (!feof(file))
                  {
                       fread(&str, sizeof(char), 1, file);
                       printf("%02x", (unsigned char)str);
                  }

                  Cela "marche", car avec ce que tu mets en arguments de fread() tu lis un char à la fois, et avec printf() et tu affiches un char à la fois.

                  D'ailleurs, en C, tu peux écrire fread(&str, 1, 1, file); car la norme du C garantit que sizeof(char) vaut 1.

                  Si tu changes le type de str en char str[1000] pour y stocker plusieurs chars, tu dois lire plusieurs chars avec fread() aussi.

                  Par exemple si tu veux lire des chars correspondant à "lorem ipsum..." (15 char en comptant les ...), cela serait fread(str, 1, 15, file);

                  https://www.cplusplus.com/reference/cstdio/fread/

                  Il te faudra connaître à l'avance le nombre de char à lire (ici 15) et terminer la chaîne C en faisant str[15] = '\0'; (à la 16ème position) si tu veux utiliser la séquence de char récupérée comme une chaîne C valide. Tu devras aussi changer le printf() pour afficher une chaîne, si c'est bien ce que tu veux faire.

                  Une autre question utile à se poser, à laquelle on ne peut pas répondre à ta place car tu connais le contexte de ce que tu fais et pas nous, c'est aussi pourquoi tu utilises fread() pour lire des char que tu veux sous forme de chaîne, ou en tout cas que tu veux stocker dans un tableau, au lieu de fonctions comme fgets() qui permettent directement d'obtenir des chaînes.

                  https://www.cplusplus.com/reference/cstdio/fgets/

                  -
                  Edité par Dlks 29 septembre 2021 à 18:46:29

                  • Partager sur Facebook
                  • Partager sur Twitter
                    29 septembre 2021 à 18:45:54

                    Nhayku a écrit:

                    C'est ce que j'ai essayé hier mais sans succès:

                    char str_cpy[1000];
                    strcpy(str_cpy, str);
                    Dans cette portion de code, que vaut str ?

                    • Partager sur Facebook
                    • Partager sur Twitter
                    ...
                      29 septembre 2021 à 18:46:23

                      Dlks a écrit:

                      Cela "marche", car avec ce que tu mets en arguments de fread() tu lis un char à la fois, et avec printf() et tu affiches un char à la fois.


                      Salut, merci beaucoup c'est exactement le soucis que je rencontrais! je me suis laissé avoir par le while qui affichait tout d'un coup.

                      Je vais donc adapter le code pour essayer de le faire fonctionner.

                      Je reviens vers vous très vite.

                      PS: Si j'utilise fread, c'est pour obtenir le contenu de chaque octet d'un fichier et non un mélange de caractère ascii. Je n'ai pas trouvé de meilleure solution en fouillant sur internet.

                      EDIT: Je viens de me rendre compte que fgetc donne le même résultat. La lecture d'un caractère ascii ou du code hexa de l'octet dépend de ce que je mets dans printf. (i.e printf("%02X", truc)).

                      Est-ce que je peux savoir si ce que je stocke est donc un code hexadécimal ou un code ascii?

                      -
                      Edité par Nhayku 29 septembre 2021 à 19:12:33

                      • Partager sur Facebook
                      • Partager sur Twitter
                        29 septembre 2021 à 18:51:26

                        str étant un char, strcpy(str_cpy,&str); devrait mieux fonctionner, et encore mieux en ayant initialiser str_cpy: char str_cpy[1000]={0}.

                        A conjuguer avec strcat(dest,chaine_a_ajouter) (voire strncat)

                        • Partager sur Facebook
                        • Partager sur Twitter
                          29 septembre 2021 à 19:06:44

                          umfred a écrit:

                          str étant un char, strcpy(str_cpy,&str); devrait mieux fonctionner

                          Ah non, ça ne fonctionnera que si, par chance, il y a un \0 juste derrière str. Et initialiser str_cpy à 0 (dans un emploi de strcpy()) ne sert à rien.

                          -
                          Edité par edgarjacobs 29 septembre 2021 à 19:09:22

                          • Partager sur Facebook
                          • Partager sur Twitter

                          On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

                            29 septembre 2021 à 19:36:42

                            > Est-ce que je peux savoir si ce que je stocke est donc un code hexadécimal ou un code ascii?
                            Ni un ni l'autre, c'est du binaire ...
                            Ça peut devenir compliqué d'expliquer tout cela.
                            Je prend la lettre 'A'. Tu la vois graphiquement.
                            Tu appuies sur la touche du clavier qui lui correspond.
                            C'est un ensemble de signaux électriques qui sont envoyés au processeur ou la mémoire.
                            Ce paquet de signaux est du binaire.
                            On peut écrire du binaire de façon condensée en hexadécimal, ou toute autre base.
                            Le code ASCII est une convention qui dit quel code on associe à un caractère graphique.
                            • Partager sur Facebook
                            • Partager sur Twitter

                            Le Tout est souvent plus grand que la somme de ses parties.

                              29 septembre 2021 à 22:35:59

                              Nhayku a écrit:

                              C'est ce que j'ai essayé hier mais sans succès:

                              char str_cpy[1000];
                              strcpy(str_cpy, str);

                              j'obtiens une erreur lors de l'exécution:

                              Violation d'accès lors de la lecture de l'emplacement 0x00000042.



                              -
                              Edité par Nhayku il y a environ 4 heures

                              Ça peut faire ça si tu as déclaré

                              char str = 'B';

                               et que tu n'as pas tenu compte des avertissements du compilateur.

                              Ps: quand tu dis ça marche pas, on sait pas de quoi tu parles. Il nous faut

                              • Une explication de ce que tu voulais que ça fasse
                              • Ce que ca fait en réalité 
                              • Le code complet, qu'on puisse reproduire le probleme, et donner une correction

                              -
                              Edité par michelbillaud 29 septembre 2021 à 22:46:20

                              • Partager sur Facebook
                              • Partager sur Twitter
                                30 septembre 2021 à 10:07:25

                                Nhayku a écrit:

                                Dlks a écrit:

                                Cela "marche", car avec ce que tu mets en arguments de fread() tu lis un char à la fois, et avec printf() et tu affiches un char à la fois.


                                Salut, merci beaucoup c'est exactement le soucis que je rencontrais! je me suis laissé avoir par le while qui affichait tout d'un coup.

                                Je vais donc adapter le code pour essayer de le faire fonctionner.

                                (...)

                                La lecture d'un caractère ascii ou du code hexa de l'octet dépend de ce que je mets dans printf. (i.e printf("%02X", truc)).

                                Est-ce que je peux savoir si ce que je stocke est donc un code hexadécimal ou un code ascii?

                                Le type char, selon la norme du C, est un type entier.

                                De façon interne, le C le stocke sous forme binaire, mais cela ne te concerne pas vraiment. Ce que tu stockes est un entier.

                                Ce char est donc un entier, qui peut être représenté sous la forme d'un caractère, d'un nombre décimal, hexadécimal, etc., selon ce que tu veux en faire et le fait de le récupérer avec fread(), fgetc() ou dans une chaîne C avec fgets() ne fait aucune différence au fait que tu récupères des char.

                                fgets() va juste te faciliter la vie en traitant des lignes et en récupérant des chaînes C:

                                • en lisant au plus le nombre de char mentionné en 2ème paramètre - 1 (tu devras mettre 999 si ton tableau est dimensionné à 1000), cela est utile, donc si tu sais que tes chaînes ne vont pas dépasser une certaine taille, mais que tu ne sais pas à l'avance si elles auront une taille de 15, 42 ou 512 chars
                                • en s'arrêtant au premier '\n', c'est à dire au premier retour à la ligne trouvé (qui est lu et récupéré dans la chaîne s'il y a assez d'espace)
                                • en ajoutant, après les char lus, le '\0' terminateur de chaîne
                                • au final, comme fgets() te permet d'obtenir une chaîne valide, tu pourras utiliser les fonctions de manipulation de chaînes standards comme strcpy()
                                 fread() ne fait pas tout cela, tu dois tout gérer manuellement.

                                -
                                Edité par Dlks 30 septembre 2021 à 10:11:21

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  1 octobre 2021 à 2:21:28

                                  Nhayku a écrit:

                                  Bonjour,

                                  char str;
                                  while (!feof(file))
                                  {
                                              
                                              fread(&str, sizeof(char), 1, file);
                                              printf("%02x", (unsigned char)str);
                                  }

                                  Pourtant, il y a un bug très classique dans ton code; je suis étonné qu'aucun participant ne l'ait déjà relevé.

                                  Il faut appeler feof après la lecture, pas avant! En effet, avant de lire, on ne peut pas savoir si la lecture a rencontré la fin du fichier!
                                  Tu peux lire https://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong pour en savoir plus.



                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    1 octobre 2021 à 11:53:37

                                    bonjour,

                                    vos échanges m'ont bien aidés! merci beaucoup!

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      1 octobre 2021 à 18:09:35

                                      Marc Mongenet a écrit:

                                      Nhayku a écrit:

                                      Bonjour,

                                      char str;
                                      while (!feof(file))
                                      {
                                                  
                                                  fread(&str, sizeof(char), 1, file);

                                      printf("%02x", (unsigned char)str); }

                                      Pourtant, il y a un bug très classique dans ton code; je suis étonné qu'aucun participant ne l'ait déjà relevé.

                                      Il faut appeler feof après la lecture, pas avant! En effet, avant de lire, on ne peut pas savoir si la lecture a rencontré la fin du fichier!

                                      Oui, tu as raison de le signaler.

                                      Personnellement, je me concentrais sur autre chose.

                                      Aussi, on ne peut pas être certain que ce soit un bogue ou pas car il ne montre qu'une partie du code, et on ne sait pas s'il lit autre chose entre l'appel à fopen() (qui n'est pas dans le code posté) et ce qu'il a posté et qui pourrait donner une pertinence à un premier appel à feof() en entrée de boucle ;-)

                                      -
                                      Edité par Dlks 1 octobre 2021 à 18:10:44

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        1 octobre 2021 à 22:06:08

                                        Bien rattrapé :-)

                                        Pour moi, j'ai pas regardé la lecture, je pense qu'il va y avoir besoin assez vite d'explications sur la notion douteuse  de "donnée stockée en binaire / en ascii" en mémoire.

                                        Quand le moment sera venu...

                                        Wait and see

                                        -
                                        Edité par michelbillaud 1 octobre 2021 à 22:11:43

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          2 octobre 2021 à 0:47:03

                                          Dlks a écrit:

                                          Marc Mongenet a écrit:

                                          Nhayku a écrit:

                                          Bonjour,

                                          char str;
                                          while (!feof(file))
                                          {
                                                      
                                                      fread(&str, sizeof(char), 1, file);

                                          printf("%02x", (unsigned char)str); }

                                          Pourtant, il y a un bug très classique dans ton code; je suis étonné qu'aucun participant ne l'ait déjà relevé.

                                          Il faut appeler feof après la lecture, pas avant! En effet, avant de lire, on ne peut pas savoir si la lecture a rencontré la fin du fichier!

                                          Aussi, on ne peut pas être certain que ce soit un bogue ou pas car il ne montre qu'une partie du code, et on ne sait pas s'il lit autre chose entre l'appel à fopen() (qui n'est pas dans le code posté) et ce qu'il a posté et qui pourrait donner une pertinence à un premier appel à feof() en entrée de boucle ;-)

                                          Oui, il pourrait exister une lecture avant le premier feof. Mais il y aurait toujours un bug: après le fread qu'on voit dans la boucle, le code commence par faire comme si fread a réussi en utilisant str dans printf. Alors qu'en fait on ne sait pas si fread a réussi. Ce n'est qu'en rebouclant, qu'il vérifie trop tard, si fread n'est pas par hasard tombé sur la fin.

                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            5 octobre 2021 à 15:47:20

                                            +1

                                            Arf, oui, tu as raison, mon rattrapage aux branches n'a pas bien fonctionné :-P

                                            • Partager sur Facebook
                                            • Partager sur Twitter

                                            Problème char et char[]

                                            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                            • Editeur
                                            • Markdown