Partage
  • Partager sur Facebook
  • Partager sur Twitter

error: assignment to expression with array type

Sujet résolu
    15 février 2023 à 19:07:27

    Bonjour, avec ce bout de code:

    	signed char* temp;
    		temp = fgets(temp, 100, file);
    		fseek(file, SEEK_CUR, SEEK_SET);
    
    		signed char utfText[]="";
    		
    		while (!feof(file)) {
    			
    			utfText = strcat(utfText, fgets(temp, 100, file));
    		}

    mon compilateur affiche:

    error: assignment to expression with array type
       43 |                         utfText = strcat(utfText, fgets(temp, 100, file));
          |                                 ^


    Auriez vous une explication puisqu'il me semble que utfText est du bon type ?

    • Partager sur Facebook
    • Partager sur Twitter
      15 février 2023 à 19:34:40

      Bonjour HenriHenri9,

      En C on ne peut pas affecter le contenu d'un tableau avec l'opérateur =, si c'est ce que tu essayes de faire.

      Tu n'utilises pas strcat correctement dans ce contexte.

      strcat renvoie un pointeur sur char, son prototype est :

      char * strcat ( char * destination, const char * source );

      https://cplusplus.com/reference/cstring/strcat/

      Si tu veux utiliser la valeur de retour de strcat, tu dois l'utiliser en tant que telle (un pointeur sur char). Cette valeur de retour est utile, par exemple, pour chaîner le résultat de strcat avec une autre commande attendant en paramètre un pointeur sur char (par exemple strcmp ou une autre fonction standard sous string.h).

      Ici, pour faire ce que tu veux, comme ton "utfText" est un tableau de char, tu peux simplement écrire :

      strcat(utfText, fgets(temp, 100, file));

      car strcat concatène de toutes façons la chaîne passée en 2nd paramètre à la fin de la chaîne passée en 1er paramètre.

      il faudra aussi que tu donnes à "utfText" une taille en le déclarant correctement et en l'initialisant correctement :

      char utfText[256] = { '\0' };

      Cela ne sert à rien de mettre "signed" devant le type "char", car le type char sans autre précisions est déjà signé.

      -
      Edité par Dlks 15 février 2023 à 19:48:38

      • Partager sur Facebook
      • Partager sur Twitter
        15 février 2023 à 21:26:45

        Merci beaucoup pour votre réponse, désormais tout(concernant ma question) fonctionne.

        • Partager sur Facebook
        • Partager sur Twitter
          16 février 2023 à 9:10:05

          Dlks a écrit:

          il faudra aussi que tu donnes à "utfText" une taille en le déclarant correctement et en l'initialisant correctement :

          char utfText[256] = { '\0' };

          Cela ne sert à rien de mettre "signed" devant le type "char", car le type char sans autre précisions est déjà signé.

          -
          Edité par Dlks il y a environ 12 heures


          Désolé d'être contrariant, mais

          •  the three types char,signed char, and unsigned char are collectively called the character types.
            The implementation shall define char to have the same range, representation, and behavior as either
            signed char or unsigned char .45
          et la note de bas de page 45 char is a separate type from the other two and is not compatible with either.



          Donc ça sert à quelque chose de mettre signed (par exemple) si le comportement du programme dépend de la présence de chars négatifs, et qu'on veut un programme écrit en C portable.

          Le plus souvent, c'est unsigned dont on a besoin, par exemple on devrait le faire chaque fois qu'on utilise getc et cie, qui retournent un int une valeur positive pour les caractères (celle d'un unsigned char) quand il y en a, et EOF (= -1) quand il n'y en a pas.  Ou alors parce que les octets contenu de la chaîne servent d'indice dans un tableau.


          Pour déclarer un tampon d'une certaine taille  initialisé par une chaîne vide, on peut aussi utilise la forme
          char tampon[256] = "";
          
          qui est plus simple à écrire.


          (1) historiquement les standards C successifs ont été rédigés, non pour fixer une norme claire qui donnerait à un programme une interprétation unique quel que soit le compilo utilisé, mais pour laisser aux marchands de compilateurs la possibilité de continuer à vendre leurs trucs qui ont suivi des choix divergents. 
          Il parait que bientôt, il sera indiqué que les entiers signés doivent être en représentation binaire complément à 2. Pour l'instant, c'est encore permis d'avoir signe+valeur absolu,  ou complément à 1. donc 2 représentations du zero...   Des trucs qui ne sont plus supportés par les processeurs conçus depuis quelques décennies.


          -
          Edité par michelbillaud 16 février 2023 à 9:30:22

          • Partager sur Facebook
          • Partager sur Twitter
            16 février 2023 à 9:19:37

            Dlks a écrit:

            Cela ne sert à rien de mettre "signed" devant le type "char", car le type char sans autre précisions est déjà signé

            Pas du tout, c'est laissé à la norme.

            Edit : grillé par michelbillaud

            Concernant le code de l'OP il y a plusieurs choses qui ne vont pas :

            • Utiliser strcat est souvent signe de risque.
            • Utiliser une boucle basée sur feof est souvent une mauvaise pratique.
            • Tu lis dans un pointeur non initialisé.
            • Tu strcat dans un tableau de 1 caractère.

            J'ai du mal à comprendre comment tu as pu en conclure « désormais tout fonctionne » ou alors ton code a changé depuis la dernière fois.

            -
            Edité par markand 16 février 2023 à 9:24:49

            • Partager sur Facebook
            • Partager sur Twitter

            git is great because Linus did it, mercurial is better because he didn't.

              16 février 2023 à 9:35:34

              > J'ai du mal à comprendre comment tu as pu en conclure « désormais tout fonctionne » ou alors ton code a changé depuis la dernière fois.

              En général, ça veut dire "j'ai bricolé mon truc qui a maintenant l'air de marcher, je suis bien incapable de dire pourquoi mais c'est pas grave, adieu"

              -
              Edité par michelbillaud 16 février 2023 à 9:36:21

              • Partager sur Facebook
              • Partager sur Twitter
                16 février 2023 à 9:42:44

                @michelbillaud et @markand,

                Au temps pour moi et merci de cette rectification concernant le type char :-)

                • Partager sur Facebook
                • Partager sur Twitter
                  16 février 2023 à 9:53:21

                  L'utilisation du feof pour la boucle, c'est une relique du temps où Pascal  était le langage de prédilection pour l'enseignement de la programmation (1).   Avec l'idée de "on s'assure qu'il teste des trucs à lire, puis on lit". (2)

                  En C l'approche est différente, on tente de lire, et si ça n'a pas marché, hé bé voila, c'est que c'est fini.

                  while (fgets(temp, sizeof(temp), file) != NULL) {
                      ....
                  }
                      

                  (1) souvent les cours de programmation Pascal étaient eux-même des transpositions du cours Fortran qui précédait.   Comme les cours de C++ pompés sur C.


                  (2) tout comme : "on s'assure que la pile n'est pas vide, et on dépile le sommet", etc.  Ça part d'une bonne idée : un type abstrait avec des primitives dessus qui font une chose, avec des préconditions (on ne demande une lecture que si on a vérifié avant).

                  -
                  Edité par michelbillaud 16 février 2023 à 10:01:03

                  • Partager sur Facebook
                  • Partager sur Twitter
                    16 février 2023 à 18:36:18

                    Je suppose que le fichier n'est pas très gros, car strcat n'est pas ce qu'il y a de plus efficace.
                    On recherche toujours la fin de chaîne avant d'insérer.
                    Je crois que j'irais plus vite avec un fgetc() directement sur la fin de la chaîne ...
                    • Partager sur Facebook
                    • Partager sur Twitter

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

                      16 février 2023 à 18:53:28

                      C'est surtout que le temps du strcat est proportionnel a la taille du résultat, donc en lisant les caractères 100 par 100, ça va coûter

                      • 100 (copies de caractères) pour le premier bloc
                      • 200 pour le second
                      • 300 pour le troisième
                      • 400 pour le quatrième
                      • etc
                      c'est à dire que ça fait un total qui est proportionnel au carré de la taille du fichier.  Une progression quadratique.

                      C'est à dire : si le vrai fichier est 10 fois plus gros qu'un fichier test, ça fera 100 fois plus.
                      (enfin ça se verra pas sur des petits fichiers, tant que le temps de calcul est négligeable par rapport au temps de lecture du fichier).
                       ---
                      Pour éviter ça (reparcourir depuis le début pour trouver où ajouter ce qui a été lu), il faut garder un pointeur sur l'endroit où on veut insérer; du genre
                      char texte[TAILLE_MAX_TEXTE] = "";
                      
                      char *fin_de_texte = texte;
                      
                      while (true) {
                          char ligne[TAILLE_MAX_LIGNE];
                          if (fgets(ligne, ....) ....) break;
                      
                          strcpy(fin_de_texte, ligne);
                          fin_de_texte += strlen(ligne);
                      }
                      
                      
                      
                      ---



                      Si le but est d'avoir le texte du fichier en mémoire, il y a une meilleure solution : mmap()  https://fr.wikipedia.org/wiki/Mmap

                      -
                      Edité par michelbillaud 16 février 2023 à 20:07:52

                      • Partager sur Facebook
                      • Partager sur Twitter

                      error: assignment to expression with array type

                      × 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