Partage
  • Partager sur Facebook
  • Partager sur Twitter

probléme fonction strcopy

    17 juin 2021 à 21:03:29

    bonjour, j'ai un warning:

    implicit declaration of function 'strncopy' is invalid in
          C99 [-Wimplicit-function-declaration]
            strncopy(nbalise->name, name_b, sizeof name_b);

    je ne sais pas comment le résoudre

    mon code:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define MAX_BAL_IN 15
    #define MAX_NAME_BAL 20
    #define max(a, b, c, d) ((a > b) ? c : d)
    #define min(a, b, c, d) ((a < b) ? c : d)
    
    typedef struct HTML HTML;
    typedef struct Balise Balise;
    struct Balise {
    	Balise *suivant, *Parent;
    	int len_suiv;
    	int numTabs, index;
    	char* name;
    };
    struct HTML
    {
    	Balise debut;
    	FILE* f;
    	char* namefile;
    };
    
    
    
    
    HTML* init_HTML(char* name_xml) {
    	HTML *html = malloc(sizeof(HTML));
    	Balise *balise = malloc(sizeof(Balise));
    	balise->numTabs = 0;
    	balise->Parent = NULL;
    	balise->suivant = malloc(MAX_BAL_IN * sizeof(Balise));
    	balise->name = malloc(MAX_NAME_BAL * sizeof(char));
    	balise->index = 0;
    	balise->len_suiv = 0;
    	html->f = NULL;
    	html->namefile = name_xml;
    	html->debut = *balise;
    	html->f = fopen(name_xml, "w");
    	if((! html->f) || html == NULL || balise == NULL){
    
    		exit(EXIT_FAILURE);
    	}
    	return html;
    }
    
    void add_balise(Balise* balise1, Balise* balise2) {
    
    	balise1->suivant[(balise1->index < MAX_BAL_IN) ? balise1->index : MAX_BAL_IN - 1] = *balise2;
    	balise1->index+= (balise1->index < MAX_BAL_IN) ? 1 : -1;
    	balise1->len_suiv++;
    }
    
    void newBalise(char* name_b, Balise* parent) {
    	Balise* nbalise = malloc(sizeof(Balise));
    
    	nbalise->suivant = NULL;
    	nbalise->name = "";
    	strncopy(nbalise->name, name_b, sizeof name_b);
    
    	nbalise->Parent = parent;
    	nbalise->numTabs = parent->numTabs + 1;
    	nbalise->index = 0;
    
    	parent->suivant[(parent->index < MAX_BAL_IN) ? parent->index : MAX_BAL_IN - 1] = *nbalise;
    	parent->index+= (parent->index < MAX_BAL_IN) ? 1 : -1;
    	parent->len_suiv++;
    
    }
    
    void fgetXML(HTML *html) {
    	
    	Balise *bal = malloc(sizeof(Balise));
    	Balise *start = &html->debut;
    	int index_for = 0;
    	for(bal = start; index_for < start->len_suiv; bal = &bal->suivant[index_for++]){
    		for(int n = 0; n < bal->numTabs; n++){
    			printf("\t");
    		}
    		printf("<%s>", bal->name);
    	} 
    }
    
    int main(int argc, char const *argv[])
    {
    	HTML *html = init_HTML("test_xml_C.xml");
    	newBalise("div", &html->debut);
    	printf("%s\n", html->debut.suivant[0].name);
    	fgetXML(html);
    	return 0;
    }




    -
    Edité par Le programmeur solitaire 17 juin 2021 à 21:07:17

    • Partager sur Facebook
    • Partager sur Twitter

    le code FAIT le bonheur (pour moi en tous cas)

      17 juin 2021 à 21:27:00

      Et bien le nom de la fonction que tu souhaites utiliser c'est : strncpy et non pas strncopy !

      Si tu souhaites vraiment utiliser strncopy, il va falloir l'écrire, car elle n'existe pas !

      • Partager sur Facebook
      • Partager sur Twitter
        17 juin 2021 à 21:31:53

        ca marche mais l y a une autre erreur:

        [1]    64122 bus error  ./HTML

        kes que c'est

        • Partager sur Facebook
        • Partager sur Twitter

        le code FAIT le bonheur (pour moi en tous cas)

          17 juin 2021 à 22:44:47

          Alors je ne sais pas ce que tu utilises comme compilo mais :

          $ gcc -Wall -Wextra -c ps.c 
          ps.c: In function ‘newBalise’:
          ps.c:59:43: warning: argument to ‘sizeof’ in ‘strncpy’ call is the same expression as the source; did you mean to provide an explicit length? [-Wsizeof-pointer-memaccess]
             59 |     strncpy(nbalise->name, name_b, sizeof name_b);
                |                                           ^~~~~~
          

          même avec clang 

          $ clang -Wall -Wextra -c ps.c 
          ps.c:59:43: warning: 'strncpy' call operates on objects of type 'char' while the size is based on a different type 'char *' [-Wsizeof-pointer-memaccess]
              strncpy(nbalise->name, name_b, sizeof name_b);
                                     ~~~~~~         ^~~~~~
          ps.c:59:43: note: did you mean to provide an explicit length?
              strncpy(nbalise->name, name_b, sizeof name_b);
                                                    ^~~~~~
          

          après si tu as une version récente de gcc tu peux carrément :

          $ gcc -g -fanalyzer -Wall -Wextra -o ps ps.c 
          ps.c: In function ‘newBalise’:
          ps.c:59:43: warning: argument to ‘sizeof’ in ‘strncpy’ call is the same expression as the source; did you mean to provide an explicit length? [-Wsizeof-pointer-memaccess]
             59 |     strncpy(nbalise->name, name_b, sizeof name_b);
                |                                           ^~~~~~
          ps.c: In function ‘main’:
          ps.c:84:14: warning: unused parameter ‘argc’ [-Wunused-parameter]
             84 | int main(int argc, char const *argv[])
                |          ~~~~^~~~
          ps.c:84:32: warning: unused parameter ‘argv’ [-Wunused-parameter]
             84 | int main(int argc, char const *argv[])
                |                    ~~~~~~~~~~~~^~~~~~
          ps.c: In function ‘init_HTML’:
          ps.c:30:21: warning: dereference of possibly-NULL ‘balise’ [CWE-690] [-Wanalyzer-possible-null-dereference]
             30 |     balise->numTabs = 0;
                |     ~~~~~~~~~~~~~~~~^~~
            ‘init_HTML’: events 1-2
              |
              |   29 |     Balise *balise = malloc(sizeof(Balise));
              |      |                      ^~~~~~~~~~~~~~~~~~~~~~
              |      |                      |
              |      |                      (1) this call could return NULL
              |   30 |     balise->numTabs = 0;
              |      |     ~~~~~~~~~~~~~~~~~~~
              |      |                     |
              |      |                     (2) ‘balise’ could be NULL: unchecked value from (1)
              |
          ps.c:36:13: warning: dereference of possibly-NULL ‘html’ [CWE-690] [-Wanalyzer-possible-null-dereference]
             36 |     html->f = NULL;
                |             ^
            ‘init_HTML’: event 1
              |
              |   28 |     HTML *html = malloc(sizeof(HTML));
              |      |                  ^~~~~~~~~~~~~~~~~~~~
              |      |                  |
              |      |                  (1) this call could return NULL
              |
            ‘init_HTML’: event 2
              |
              |   36 |     html->f = NULL;
              |      |             ^
              |      |             |
              |      |             (2) ‘html’ could be NULL: unchecked value from (1)
              |
          ps.c:44:12: warning: leak of ‘balise’ [CWE-401] [-Wanalyzer-malloc-leak]
             44 |     return html;
                |            ^~~~
            ‘init_HTML’: events 1-5
              |
              |   29 |     Balise *balise = malloc(sizeof(Balise));
              |      |                      ^~~~~~~~~~~~~~~~~~~~~~
              |      |                      |
              |      |                      (1) allocated here
              |   30 |     balise->numTabs = 0;
              |      |     ~~~~~~~~~~~~~~~~~~~
              |      |                     |
              |      |                     (2) assuming ‘balise’ is non-NULL
              |......
              |   40 |     if((! html->f) || html == NULL || balise == NULL){
              |      |       ~               
              |      |       |
              |      |       (3) following ‘false’ branch...
              |......
              |   44 |     return html;
              |      |            ~~~~       
              |      |            |
              |      |            (4) ...to here
              |      |            (5) ‘balise’ leaks here; was allocated at (1)
              |
          ps.c: In function ‘newBalise’:
          ps.c:57:22: warning: dereference of possibly-NULL ‘nbalise’ [CWE-690] [-Wanalyzer-possible-null-dereference]
             57 |     nbalise->suivant = NULL;
                |                      ^
            ‘newBalise’: event 1
              |
              |   55 |     Balise* nbalise = malloc(sizeof(Balise));
              |      |                       ^~~~~~~~~~~~~~~~~~~~~~
              |      |                       |
              |      |                       (1) this call could return NULL
              |
            ‘newBalise’: event 2
              |
              |   57 |     nbalise->suivant = NULL;
              |      |                      ^
              |      |                      |
              |      |                      (2) ‘nbalise’ could be NULL: unchecked value from (1)
              |
          ps.c:69:1: warning: leak of ‘nbalise’ [CWE-401] [-Wanalyzer-malloc-leak]
             69 | }
                | ^
            ‘newBalise’: event 1
              |
              |   55 |     Balise* nbalise = malloc(sizeof(Balise));
              |      |                       ^~~~~~~~~~~~~~~~~~~~~~
              |      |                       |
              |      |                       (1) allocated here
              |
            ‘newBalise’: events 2-3
              |
              |   57 |     nbalise->suivant = NULL;
              |      |                      ^
              |      |                      |
              |      |                      (2) assuming ‘nbalise’ is non-NULL
              |......
              |   69 | }
              |      | ~                     
              |      | |
              |      | (3) ‘nbalise’ leaks here; was allocated at (1)
              |
          ps.c: In function ‘fgetXML’:
          ps.c:76:13: warning: leak of ‘bal’ [CWE-401] [-Wanalyzer-malloc-leak]
             76 |     for(bal = start; index_for < start->len_suiv; bal = &bal->suivant[index_for++]){
                |         ~~~~^~~~~~~
            ‘fgetXML’: events 1-2
              |
              |   73 |     Balise *bal = malloc(sizeof(Balise));
              |      |                   ^~~~~~~~~~~~~~~~~~~~~~
              |      |                   |
              |      |                   (1) allocated here
              |......
              |   76 |     for(bal = start; index_for < start->len_suiv; bal = &bal->suivant[index_for++]){
              |      |         ~~~~~~~~~~~
              |      |             |
              |      |             (2) ‘bal’ leaks here; was allocated at (1)
              |
          ps.c: In function ‘main’:
          ps.c:88:5: warning: dereference of possibly-NULL ‘*html.debut.suivant’ [CWE-690] [-Wanalyzer-possible-null-dereference]
             88 |     printf("%s\n", html->debut.suivant[0].name);
                |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            ‘main’: events 1-2
              |
              |   84 | int main(int argc, char const *argv[])
              |      |     ^~~~
              |      |     |
              |      |     (1) entry to ‘main’
              |   85 | {
              |   86 |     HTML *html = init_HTML("test_xml_C.xml");
              |      |                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~
              |      |                  |
              |      |                  (2) calling ‘init_HTML’ from ‘main’
              |
              +--> ‘init_HTML’: events 3-6
                     |
                     |   27 | HTML* init_HTML(char* name_xml) {
                     |      |       ^~~~~~~~~
                     |      |       |
                     |      |       (3) entry to ‘init_HTML’
                     |......
                     |   32 |     balise->suivant = malloc(MAX_BAL_IN * sizeof(Balise));
                     |      |                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                     |      |                       |
                     |      |                       (4) this call could return NULL
                     |......
                     |   40 |     if((! html->f) || html == NULL || balise == NULL){
                     |      |       ~
                     |      |       |
                     |      |       (5) following ‘false’ branch...
                     |......
                     |   44 |     return html;
                     |      |            ~~~~
                     |      |            |
                     |      |            (6) ...to here
                     |
              <------+
              |
            ‘main’: events 7-8
              |
              |   86 |     HTML *html = init_HTML("test_xml_C.xml");
              |      |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~
              |      |                  |
              |      |                  (7) returning to ‘main’ from ‘init_HTML’
              |   87 |     newBalise("div", &html->debut);
              |      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              |      |     |
              |      |     (8) calling ‘newBalise’ from ‘main’
              |
              +--> ‘newBalise’: events 9-13
                     |
                     |   54 | void newBalise(char* name_b, Balise* parent) {
                     |      |      ^~~~~~~~~
                     |      |      |
                     |      |      (9) entry to ‘newBalise’
                     |......
                     |   65 |     parent->suivant[(parent->index < MAX_BAL_IN) ? parent->index : MAX_BAL_IN - 1] = *nbalise;
                     |      |                    ~                               ~~~~~~~~~~~~~
                     |      |                    |                                     |
                     |      |                    |                                     (11) ...to here
                     |      |                    (10) following ‘true’ branch...
                     |   66 |     parent->index+= (parent->index < MAX_BAL_IN) ? 1 : -1;
                     |      |                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                     |      |                                                      |
                     |      |                                                      (12) following ‘true’ branch...
                     |      |                                                      (13) ...to here
                     |
              <------+
              |
            ‘main’: events 14-15
              |
              |   87 |     newBalise("div", &html->debut);
              |      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              |      |     |
              |      |     (14) possible return of NULL to ‘main’ from ‘newBalise’
              |   88 |     printf("%s\n", html->debut.suivant[0].name);
              |      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              |      |     |
              |      |     (15) ‘*html.debut.suivant’ could be NULL: unchecked value from (4)
              |
          

          et sinon tu peux toujours passer ton code sur valgrind :

          $ valgrind --leak-check=full --track-origins=yes --show-reachable=yes ./ps
          ==35854== Memcheck, a memory error detector
          ==35854== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
          ==35854== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
          ==35854== Command: ./ps
          ==35854== 
          ==35854== 
          ==35854== Process terminating with default action of signal 11 (SIGSEGV): dumping core
          ==35854==  Bad permissions for mapped region at address 0x10A006
          ==35854==    at 0x4844DA8: __strncpy_sse2_unaligned (vg_replace_strmem.c:567)
          ==35854==    by 0x1093AC: newBalise (ps.c:59)
          ==35854==    by 0x109559: main (ps.c:87)
          ==35854== 
          

          sans lire une seule ligne de ton code, je peux te dire que tu utilises mal strncpy non seulement à cause du warning mais aussi de valgrind qui pointe cette ligne …

          il va falloir apprendre à débuguer sans passer par un forum et peut-être aussi à limiter ton enthousiasme et t'attaquer à des programmes plus simples.




          • Partager sur Facebook
          • Partager sur Twitter
            18 juin 2021 à 8:23:43

            je sais mais pourtant j'ai enlevé le sizeof et remplacé par strlen plus de bus error mais ca m'affiche ceci:

            <p?9?>

            une idée?

            -
            Edité par Le programmeur solitaire 18 juin 2021 à 8:27:23

            • Partager sur Facebook
            • Partager sur Twitter

            le code FAIT le bonheur (pour moi en tous cas)

              18 juin 2021 à 9:18:17

              ta structure Balise contient un champ name q2ui est un pointeur sur char. Tu l'utilises sans l'initialiser ; il te faudrait par exemple allouer un peu de mémoire pour pouvoir y copier ce que tu veux.

              • Partager sur Facebook
              • Partager sur Twitter
                18 juin 2021 à 12:33:49

                Utilise un debugger et active les warnings. La programmation c'est pas de la devinette.
                • Partager sur Facebook
                • Partager sur Twitter

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

                  18 juin 2021 à 12:55:06

                  markand a écrit:

                  Utilise un debugger et active les warnings. La programmation c'est pas de la devinette.


                  je pense que c'est hors de sa portée. Ptêt qu'il doit juste finir un truc et qu'il s'en fout du reste ?
                  • Partager sur Facebook
                  • Partager sur Twitter
                    18 juin 2021 à 17:08:50

                    White Crow a écrit:

                    ta structure Balise contient un champ name q2ui est un pointeur sur char. Tu l'utilises sans l'initialiser ; il te faudrait par exemple allouer un peu de mémoire pour pouvoir y copier ce que tu veux.

                    je ne comprends pas , je l'ai fait depuis longtemps:

                    balise->name = malloc(MAX_NAME_BAL * sizeof(char));



                    ou encore :

                    nbalise->name = malloc(MAX_NAME_BAL*sizeof(char));

                    je ne comprends parce que ensuite:

                    strncpy(nbalise->name, name_b, strlen(name_b));

                    merci de votre aide

                    PS: pourtant ca marche ici :

                    printf("%s\n", html->debut.suivant[0].name);

                    qui affiche "div"


                    -
                    Edité par Le programmeur solitaire 18 juin 2021 à 17:16:39

                    • Partager sur Facebook
                    • Partager sur Twitter

                    le code FAIT le bonheur (pour moi en tous cas)

                      18 juin 2021 à 17:37:18

                      Cela fait plusieurs fois que je te parle de la ligne 59 ...

                      Mais comme dit markand : utilise un debuger !

                      • Partager sur Facebook
                      • Partager sur Twitter
                        18 juin 2021 à 17:53:14

                        White Crow a écrit:

                        Cela fait plusieurs fois que je te parle de la ligne 59 ...

                        Mais comme dit markand : utilise un debuger !


                        je ne comprends pas?
                        • Partager sur Facebook
                        • Partager sur Twitter

                        le code FAIT le bonheur (pour moi en tous cas)

                          18 juin 2021 à 18:13:18

                          ta ligne 58 initialise le pointeur vers une chaîne non modifiable, il faut allouer un espace mémoire … 

                          après si tu as modifié ton code en ligne 58 … je ne peux pas le deviner.

                          • Partager sur Facebook
                          • Partager sur Twitter
                            18 juin 2021 à 18:18:01

                            mon nouveau code:

                            #include <stdio.h>
                            #include <stdlib.h>
                            #include <string.h>
                            #define MAX_BAL_IN 15
                            #define MAX_NAME_BAL 20
                            #define max(a, b, c, d) ((a > b) ? c : d)
                            #define min(a, b, c, d) ((a < b) ? c : d)
                            
                            typedef struct HTML HTML;
                            typedef struct Balise Balise;
                            struct Balise {
                            	Balise *suivant, *Parent;
                            	int len_suiv;
                            	int numTabs, index;
                            	char *name;
                            };
                            struct HTML
                            {
                            	Balise debut;
                            	FILE* f;
                            	char* namefile;
                            };
                            
                            
                            
                            
                            HTML* init_HTML(char* name_xml) {
                            	HTML *html = malloc(sizeof(HTML));
                            	Balise *balise = malloc(sizeof(Balise));
                            	balise->numTabs = 0;
                            	balise->Parent = NULL;
                            	balise->suivant = malloc(MAX_BAL_IN * sizeof(Balise));
                            	balise->name = malloc(MAX_NAME_BAL * sizeof(char));
                            	balise->index = 0;
                            	balise->len_suiv = 0;
                            	html->f = NULL;
                            	html->namefile = name_xml;
                            	html->debut = *balise;
                            	html->f = fopen(name_xml, "w");
                            	if((! html->f) || html == NULL || balise == NULL){
                            
                            		exit(EXIT_FAILURE);
                            	}
                            	return html;
                            }
                            
                            void add_balise(Balise* balise1, Balise* balise2) {
                            
                            	balise1->suivant[(balise1->index < MAX_BAL_IN) ? balise1->index : MAX_BAL_IN - 1] = *balise2;
                            	balise1->index+= (balise1->index < MAX_BAL_IN) ? 1 : -1;
                            	balise1->len_suiv++;
                            }
                            
                            void newBalise(char* name_b, Balise* parent) {
                            	Balise* nbalise = malloc(sizeof(Balise));
                            
                            	nbalise->suivant = malloc(MAX_BAL_IN * sizeof(Balise));
                            	nbalise->name = malloc(MAX_NAME_BAL*sizeof(char));
                            	strncpy(nbalise->name, name_b, strlen(name_b));
                            
                            	nbalise->Parent = parent;
                            	nbalise->numTabs = parent->numTabs + 1;
                            	nbalise->index = 0;
                            
                            	parent->suivant[(parent->index < MAX_BAL_IN) ? parent->index : MAX_BAL_IN - 1] = *nbalise;
                            	parent->index+= (parent->index < MAX_BAL_IN) ? 1 : -1;
                            	parent->len_suiv++;
                            	
                            
                            	
                            }
                            
                            void getXML(HTML *html) {
                            	
                            	Balise *bal = malloc(sizeof(Balise));
                            	Balise *start = &html->debut;
                            	int index_for = 0;
                            	for(bal = start; index_for < start->len_suiv; bal = &bal->suivant[index_for++]){
                            		for(int n = 0; n < bal->numTabs; n++){
                            			printf("\t");
                            		}
                            		
                            		printf("<%s>\n", bal->name);
                            	} 
                            }
                            
                            int main(void)
                            {
                            	HTML *html = init_HTML("test_xml_C.xml");
                            	char n[] = "div";
                            	newBalise(n, &html->debut);
                            	printf("%s\n", html->debut.suivant[0].name);
                            	getXML(html);
                            	return 0;
                            }





                            -
                            Edité par Le programmeur solitaire 18 juin 2021 à 18:24:28

                            • Partager sur Facebook
                            • Partager sur Twitter

                            le code FAIT le bonheur (pour moi en tous cas)

                              18 juin 2021 à 18:58:21

                              Le programmeur solitaire a écrit:

                              mon nouveau code

                              Oui,... Tu en es satisfait ?

                              Pour en revenir à ta question initiale, La façon dont tu utilises strncpy , fait que tu utiliserais strcpy ça ferait (presque *) pareil !

                              * presque, parce que tu ne tiens pas compte du caractère de fin de chaîne.

                              Pour strncpy si on met une taille, c'est pour ne pas déborder dans le buffer de destination, alors que toi tu n'en tiens pas compte de la façon dont tu procèdes.

                              • Partager sur Facebook
                              • Partager sur Twitter
                                18 juin 2021 à 19:01:36

                                Plutôt que de faire :

                                   balise->name = malloc(MAX_NAME_BAL * sizeof(char));

                                tu pourrais faire (plus simple) :

                                struct Balise {
                                    Balise *suivant, *Parent;
                                    int len_suiv;
                                    int numTabs, index;
                                    char name[MAX_NAME_BAL];   // le tableau est alloué, pas besoin de malloc
                                };

                                L'allocation dynamique, je trouve que c'est bien uniquement si on n'a pas le choix...

                                -
                                Edité par robun 18 juin 2021 à 19:02:01

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  18 juin 2021 à 19:05:54

                                  le plus drôle (croyez moi ou pas) c'est que je l'avais fait mais je me suis dit que le malloc revenait à la même chose.

                                  il y a eu un changement: 

                                  au lieu de m'afficher <p??> il m'affiche <> déjà c'est juste un bug

                                  -
                                  Edité par Le programmeur solitaire 18 juin 2021 à 19:08:02

                                  • Partager sur Facebook
                                  • Partager sur Twitter

                                  le code FAIT le bonheur (pour moi en tous cas)

                                    20 juin 2021 à 8:25:00

                                    Utilise un debugger.

                                    Et au passage strncpy est probablement une des fonctions les plus pourries de la bibliothèque du C. Elle ne fait pas ce qu'on pense, en général on recommande l'utilisation de snprintf ou strlcpy (extension BSD qui va devrait être dans POSIX bientôt).

                                    • Partager sur Facebook
                                    • Partager sur Twitter

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

                                      20 juin 2021 à 8:28:01

                                      markand a écrit:

                                      Utilise un debugger.

                                      Et au passage strncpy est probablement une des fonctions les plus pourries de la bibliothèque du C. Elle ne fait pas ce qu'on pense, en général on recommande l'utilisation de snprintf ou strlcpy (extension BSD qui va devrait être dans POSIX bientôt).


                                      en faite j'ai réussi sans ses fonctions: j'ai remplacé les malloc par les [] et ca a marché je ne sais pas pourquoi
                                      • Partager sur Facebook
                                      • Partager sur Twitter

                                      le code FAIT le bonheur (pour moi en tous cas)

                                        20 juin 2021 à 9:02:11

                                        Le programmeur solitaire a écrit: > [...] et ca a marché je ne sais pas pourquoi

                                        Bonne chance et bon courage pour la suite. Il faudrait suivre un cours et ne pas t'attaquer à quelque chose qui est pour l'instant hors de la portée de ta compréhension du C.

                                        Tu pourrais essayer le cours C du zeste de savoir

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          8 juillet 2021 à 11:35:47

                                          markand a écrit:

                                          Utilise un debugger.

                                          Et au passage strncpy est probablement une des fonctions les plus pourries de la bibliothèque du C. Elle ne fait pas ce qu'on pense, en général on recommande l'utilisation de snprintf ou strlcpy (extension BSD qui va devrait être dans POSIX bientôt).

                                          asprintf finira un jour par arriver dans le standard du langage

                                          en attendant https://www.cs.helsinki.fi/group/boi2016/doc/cppreference/reference/en.cppreference.com/w/c/experimental/dynamic.html

                                          il en est là

                                          https://www.iso.org/obp/ui/#iso:std:51678:en

                                          ISO/IEC TR 24731 provides alternative functions for the C library that promote safer, more secure programming. ISO/IEC TR 24731-1 provides simple replacement functions for the library functions of ISO/IEC 9899:1999 that provide bounds checking. Those functions can be used as simple replacements for the original library functions in legacy code. ISO/IEC TR 24731-2:2010 presents replacements for many of these functions that use dynamically allocated memory to ensure that buffer overflow does not occur.

                                          (on pourrait aussi imaginer une version qui, comme getline(), alloue/utilise/agrandit au besoin un buffer alloué dynamiquement)

                                          -
                                          Edité par michelbillaud 8 juillet 2021 à 11:38:07

                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            8 juillet 2021 à 12:53:43

                                            Le programmeur solitaire a écrit:

                                            en faite j'ai réussi sans ses fonctions: j'ai remplacé les malloc par les [] et ca a marché je ne sais pas pourquoi

                                            Un pointeur sur char n'est pas la même chose d'un tableau. Donc, lorsque tu utilises l'opérateur sizeof sur l'un ou l'autre, il est normal d'obtenir des résultats différents.

                                            #include <stdio.h>
                                            #include <string.h>
                                            
                                            int main(void) {
                                                char array[10] = "1";
                                                char * pchar   = "1";
                                            
                                                printf("sizeof array = %zu\n", sizeof array);
                                                printf("sizeof pchar = %zu\n", sizeof pchar);
                                            
                                                return 0;
                                            }
                                            

                                            Tu as la taille du pointeur qui s'affiche, et non pas la taille occupée par les données pointées. Lorsque tu utilises un pointeur sur char, tu ne peux pas utiliser sizeof ni pour déterminer la longueur d'une chaîne, ni pour déterminer l'espace mémoire alloué sur ce pointeur. Pour disposer de la taille de l'espace mémoire alloué sur un pointeur, tu dois conserver cette information au moment où tu alloues la mémoire.

                                            Pour une chaîne C, sizeof déterminera par contre bien l'espace mémoire disponible pour la chaîne s'il s'agit d'un tableau.

                                            Ensuite, cela a été dit, mais je ne suis pas certain que cela ait cliqué dans ton esprit, si tu décides d'utiliser strncpy() bien qu'elle soit très imparfaite :

                                            • la taille à passer en 3ème paramètre est la taille maximale des données à copier dans l'espace mémoire indiqué en 1er paramètre (destination) à partir de l'espace mémoire en 2ème paramètre (source)
                                            • tu dois donc t'assurer de ne pas dépasser cette capacité au 1er paramètre et d'être en mesure de terminer la chaîne
                                            • tu dois t'assurer que tu termines la chaîne C, parce que strncpy() ne le fait pas pour toi si la destination est plus petite
                                            #include <stdio.h>
                                            #include <string.h>
                                            
                                            int main(void) {
                                                char array_petit[5];
                                                char array_grand[15] = "saperlipopette";
                                            
                                                strncpy(array_petit, array_grand, sizeof array_petit);
                                                array_petit[sizeof array_petit] = '\0';
                                                printf("array_petit = %s\n", array_petit);
                                            
                                                return 0;
                                            }
                                            



                                            -
                                            Edité par Dlks 8 juillet 2021 à 12:57:37

                                            • Partager sur Facebook
                                            • Partager sur Twitter

                                            probléme fonction strcopy

                                            × 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