dont chaque ligne a un nombre variable et inconnu de caractères.
Je cherche a lire ligne par ligne le fichier, et a stocker dans un
tableau de chaine ces lignes. Chaque chaine du tableau doit avoir la
bonne taille, pas trop grande.
Mon code marche pour les n-1 premières lignes, car je détecte et
supprime le '\n' conservé par fgets, le problème est pour la dernière
ligne... voici mon code, que me proposez vous ?
tbuf = malloc(n*sizeof(*tbuf)); /*alloue le tableau de chaines*/
if(tbuf)
{
while(fgets(ligne,sizeof(ligne),pf))
{
p = strchr(ligne,'\n'); /*recherche le \n*/
if(p && !cpt) /*on l'a trouve du premier coup*/
{
*p = 0; /*on le supprime*/
size = strlen(ligne); /*recupere la taille*/
buf = malloc(size); /*alloue un buffer de la taille qui va bien*/
if(buf)
{
strcpy(buf,ligne);
tbuf[cptl] = buf;
cptl++;
cpt = 0;
}
}
else if(p && cpt) /*on l'a trouve, mais pas au 1er coup*/
{
*p = 0;
size = strlen(ligne); /*recupere la taille*/
buf_tmp = realloc(buf,sizet + size);
if(buf_tmp)
{
buf = buf_tmp;
strcat(buf,ligne);
tbuf[cptl] = buf;
cptl++;
cpt = 0;
}
}
else if(!p && !cpt) /*1er coup, pas trouve*/
{
buf = malloc(sizeof(ligne)); /*on recopie dans un buffer*/
if(buf)
{
strcpy(buf,ligne);
sizet += sizeof(ligne);
cpt++;
}
}
else if(!p && cpt) /*pas trouve n-ieme coup*/
{
buf_tmp = realloc(buf,sizet + sizeof(ligne));
if(buf_tmp)
{
buf = buf_tmp;
strcat(buf,ligne);
sizet += sizeof(ligne);
cpt++;
}
}
}
}
return tbuf;
}
le problème pour la dernière ligne, c'est que je ne connais pas sa
taille, il est possible qu'elle ne rentre pas dans ma chaine temporaire
'ligne', et qu'il faille plusieurs fgets() pour la lire... or mon moyen
de détection pour la fin d'une chaine c'est justement le \n qui manque
pour celle-ci :(
le problème pour la dernière ligne, c'est que je ne connais pas sa taille, il est possible qu'elle ne rentre pas dans ma chaine temporaire 'ligne', et qu'il faille plusieurs fgets() pour la lire... or mon moyen de détection pour la fin d'une chaine c'est justement le n qui manque pour celle-ci :(
ok je me corrige tout seul, j'ai rajouté ceci dans le while :
le problème pour la dernière ligne, c'est que je ne connais pas sa taille, il
est possible qu'elle ne rentre pas dans ma chaine temporaire 'ligne', et
qu'il faille plusieurs fgets() pour la lire... or mon moyen de détection pour
la fin d'une chaine c'est justement le n qui manque pour celle-ci :(
ok je me corrige tout seul, j'ai rajouté ceci dans le while :
le problème pour la dernière ligne, c'est que je ne connais pas sa taille, il est possible qu'elle ne rentre pas dans ma chaine temporaire 'ligne', et qu'il faille plusieurs fgets() pour la lire... or mon moyen de détection pour la fin d'une chaine c'est justement le n qui manque pour celle-ci :(
ok je me corrige tout seul, j'ai rajouté ceci dans le while :
le problème pour la dernière ligne, c'est que je ne connais pas sa taille, il est possible qu'elle ne rentre pas dans ma chaine temporaire 'ligne', et qu'il faille plusieurs fgets() pour la lire... or mon moyen de détection pour la fin d'une chaine c'est justement le n qui manque pour celle-ci :(
le code me paraît bien complexe, pourquoi ne donnes-tu pas plus d'abstraction à tout cela ?
je te propose de placer une structure de données : - string_table - string_table * string_table_new(void); - my_string_table_add(string_table * table, my_string * string); - void my_string_table_free(string_table * table);
- my_string qui te permettra de manipuler les chaînes de caractères de façon aisées. - my_string * my_string_new(void); - my_string_append(my_string * string, char * data); - my_string_remove_lf(my_string * string); - void my_string_free(string);
- read_line() qui te permettra de lire une ligne complète dans un fichier texte. Cette fonction allouera une chaîne de type my_string. - my_string * read_line(FILE * f);
ton programme sera ainsi plus clair.
-- DINH V. Hoa,
"tu as bientot 15 ans, faut que tu commences à être autonome" -- jul
le problème pour la dernière ligne, c'est que je ne connais pas sa
taille, il est possible qu'elle ne rentre pas dans ma chaine temporaire
'ligne', et qu'il faille plusieurs fgets() pour la lire... or mon moyen
de détection pour la fin d'une chaine c'est justement le n qui manque
pour celle-ci :(
le code me paraît bien complexe, pourquoi ne donnes-tu pas plus
d'abstraction à tout cela ?
je te propose de placer une structure de données :
- string_table
- string_table * string_table_new(void);
- my_string_table_add(string_table * table, my_string * string);
- void my_string_table_free(string_table * table);
- my_string qui te permettra de manipuler les chaînes de caractères de
façon aisées.
- my_string * my_string_new(void);
- my_string_append(my_string * string, char * data);
- my_string_remove_lf(my_string * string);
- void my_string_free(string);
- read_line() qui te permettra de lire une ligne complète dans un
fichier texte. Cette fonction allouera une chaîne de type
my_string.
- my_string * read_line(FILE * f);
ton programme sera ainsi plus clair.
--
DINH V. Hoa,
"tu as bientot 15 ans, faut que tu commences à être autonome" -- jul
le problème pour la dernière ligne, c'est que je ne connais pas sa taille, il est possible qu'elle ne rentre pas dans ma chaine temporaire 'ligne', et qu'il faille plusieurs fgets() pour la lire... or mon moyen de détection pour la fin d'une chaine c'est justement le n qui manque pour celle-ci :(
le code me paraît bien complexe, pourquoi ne donnes-tu pas plus d'abstraction à tout cela ?
je te propose de placer une structure de données : - string_table - string_table * string_table_new(void); - my_string_table_add(string_table * table, my_string * string); - void my_string_table_free(string_table * table);
- my_string qui te permettra de manipuler les chaînes de caractères de façon aisées. - my_string * my_string_new(void); - my_string_append(my_string * string, char * data); - my_string_remove_lf(my_string * string); - void my_string_free(string);
- read_line() qui te permettra de lire une ligne complète dans un fichier texte. Cette fonction allouera une chaîne de type my_string. - my_string * read_line(FILE * f);
ton programme sera ainsi plus clair.
-- DINH V. Hoa,
"tu as bientot 15 ans, faut que tu commences à être autonome" -- jul
Nico
DINH Viêt Hoà avait soumis l'idée :
le code me paraît bien complexe, pourquoi ne donnes-tu pas plus d'abstraction à tout cela ?
je te propose de placer une structure de données : - string_table - string_table * string_table_new(void); - my_string_table_add(string_table * table, my_string * string); - void my_string_table_free(string_table * table);
- my_string qui te permettra de manipuler les chaînes de caractères de façon aisées. - my_string * my_string_new(void); - my_string_append(my_string * string, char * data); - my_string_remove_lf(my_string * string); - void my_string_free(string);
- read_line() qui te permettra de lire une ligne complète dans un fichier texte. Cette fonction allouera une chaîne de type my_string. - my_string * read_line(FILE * f);
ton programme sera ainsi plus clair.
beh je fais déjà pas mal "d'objets" perso, que j'utilise dans des programmes, et que je stocke dans une biblio perso, cependant, cette fonction est destinée à n'être lue que par moi... l'utilisateur ne verrait que son proto, et le char *, comme un objet de plus haut niveau qu'il est dans le C de base, donc je vois pas trop trop l'intéret de me casser la tête a encapsuler tout ça dans un my_string...
j'avoue c'est aussi la hâte d'avoir du résultat, et la fénéantise de refaire tout un module string
le code me paraît bien complexe, pourquoi ne donnes-tu pas plus
d'abstraction à tout cela ?
je te propose de placer une structure de données :
- string_table
- string_table * string_table_new(void);
- my_string_table_add(string_table * table, my_string * string);
- void my_string_table_free(string_table * table);
- my_string qui te permettra de manipuler les chaînes de caractères de
façon aisées.
- my_string * my_string_new(void);
- my_string_append(my_string * string, char * data);
- my_string_remove_lf(my_string * string);
- void my_string_free(string);
- read_line() qui te permettra de lire une ligne complète dans un
fichier texte. Cette fonction allouera une chaîne de type
my_string.
- my_string * read_line(FILE * f);
ton programme sera ainsi plus clair.
beh je fais déjà pas mal "d'objets" perso, que j'utilise dans des
programmes, et que je stocke dans une biblio perso, cependant, cette
fonction est destinée à n'être lue que par moi... l'utilisateur ne
verrait que son proto, et le char *, comme un objet de plus haut niveau
qu'il est dans le C de base, donc je vois pas trop trop l'intéret de me
casser la tête a encapsuler tout ça dans un my_string...
j'avoue c'est aussi la hâte d'avoir du résultat, et la fénéantise de
refaire tout un module string
le code me paraît bien complexe, pourquoi ne donnes-tu pas plus d'abstraction à tout cela ?
je te propose de placer une structure de données : - string_table - string_table * string_table_new(void); - my_string_table_add(string_table * table, my_string * string); - void my_string_table_free(string_table * table);
- my_string qui te permettra de manipuler les chaînes de caractères de façon aisées. - my_string * my_string_new(void); - my_string_append(my_string * string, char * data); - my_string_remove_lf(my_string * string); - void my_string_free(string);
- read_line() qui te permettra de lire une ligne complète dans un fichier texte. Cette fonction allouera une chaîne de type my_string. - my_string * read_line(FILE * f);
ton programme sera ainsi plus clair.
beh je fais déjà pas mal "d'objets" perso, que j'utilise dans des programmes, et que je stocke dans une biblio perso, cependant, cette fonction est destinée à n'être lue que par moi... l'utilisateur ne verrait que son proto, et le char *, comme un objet de plus haut niveau qu'il est dans le C de base, donc je vois pas trop trop l'intéret de me casser la tête a encapsuler tout ça dans un my_string...
j'avoue c'est aussi la hâte d'avoir du résultat, et la fénéantise de refaire tout un module string
beh je fais déjà pas mal "d'objets" perso, que j'utilise dans des programmes, et que je stocke dans une biblio perso, cependant, cette fonction est destinée à n'être lue que par moi... l'utilisateur ne verrait que son proto, et le char *, comme un objet de plus haut niveau qu'il est dans le C de base, donc je vois pas trop trop l'intéret de me casser la tête a encapsuler tout ça dans un my_string...
j'avoue c'est aussi la hâte d'avoir du résultat, et la fénéantise de refaire tout un module string
rien ne t'empêche d'utiliser my_string uniquement en interne puis d'extraire la chaîne obtenue de my_string. le but de faire cette structure de données est de séparer le problème en plusieurs parties simples au lieu d'essayer de résoudre un gros problème assez complexe.
-- DINH V. Hoa,
"tu as bientot 15 ans, faut que tu commences à être autonome" -- jul
beh je fais déjà pas mal "d'objets" perso, que j'utilise dans des
programmes, et que je stocke dans une biblio perso, cependant, cette
fonction est destinée à n'être lue que par moi... l'utilisateur ne
verrait que son proto, et le char *, comme un objet de plus haut niveau
qu'il est dans le C de base, donc je vois pas trop trop l'intéret de me
casser la tête a encapsuler tout ça dans un my_string...
j'avoue c'est aussi la hâte d'avoir du résultat, et la fénéantise de
refaire tout un module string
rien ne t'empêche d'utiliser my_string uniquement en interne
puis d'extraire la chaîne obtenue de my_string.
le but de faire cette structure de données est de séparer le problème en
plusieurs parties simples au lieu d'essayer de résoudre un gros problème
assez complexe.
--
DINH V. Hoa,
"tu as bientot 15 ans, faut que tu commences à être autonome" -- jul
beh je fais déjà pas mal "d'objets" perso, que j'utilise dans des programmes, et que je stocke dans une biblio perso, cependant, cette fonction est destinée à n'être lue que par moi... l'utilisateur ne verrait que son proto, et le char *, comme un objet de plus haut niveau qu'il est dans le C de base, donc je vois pas trop trop l'intéret de me casser la tête a encapsuler tout ça dans un my_string...
j'avoue c'est aussi la hâte d'avoir du résultat, et la fénéantise de refaire tout un module string
rien ne t'empêche d'utiliser my_string uniquement en interne puis d'extraire la chaîne obtenue de my_string. le but de faire cette structure de données est de séparer le problème en plusieurs parties simples au lieu d'essayer de résoudre un gros problème assez complexe.
-- DINH V. Hoa,
"tu as bientot 15 ans, faut que tu commences à être autonome" -- jul
Etienne de Tocqueville
Nico a écrit sur fr.comp.lang.c :
dont chaque ligne a un nombre variable et inconnu de caractères. Je cherche a lire ligne par ligne le fichier, et a stocker dans un tableau de chaine ces lignes. Chaque chaine du tableau doit avoir la bonne taille, pas trop grande.
En Tcl, ça prend une seule ligne pour faire ça : set list [split [read $f] 'n'] mais bon, s'il faut vraiment le faire en C... ;-)
Mon code marche pour les n-1 premières lignes, car je détecte et supprime le 'n' conservé par fgets, le problème est pour la dernière ligne... voici mon code, que me proposez vous ?
Ton code me parait trop compliqué pour le travail à faire, et en fait je dois avouer que je n'ai pas compris comment tu déterminais "n" lorsque tu appelais ta fonction str_readnline
En plus, je trouve la série de "if" superflue, générant du code redondant. Et il me semble que tu gères mal les lignes de moins de 10 caractères (c'est à dire si "ligne" contient deux "n"). En fait même, je n'ai pas bien compris ce que tu faisais d ce qui suivait le "n" que tu venait de lire...
Un truc cloche aussi : tu ne copie pas le ' ' dans ton tableau, et comme tu ne stocke nulle part la longueur de la chaine, je ne vois pas trop comment tu pourrais exploitable le résultat stocké par la suite...
Nico <nicolas.aunai@free.fr> a écrit sur fr.comp.lang.c :
dont chaque ligne a un nombre variable et inconnu de caractères.
Je cherche a lire ligne par ligne le fichier, et a stocker dans un
tableau de chaine ces lignes. Chaque chaine du tableau doit avoir la
bonne taille, pas trop grande.
En Tcl, ça prend une seule ligne pour faire ça :
set list [split [read $f] 'n']
mais bon, s'il faut vraiment le faire en C... ;-)
Mon code marche pour les n-1 premières lignes, car je détecte et
supprime le 'n' conservé par fgets, le problème est pour la dernière
ligne... voici mon code, que me proposez vous ?
Ton code me parait trop compliqué pour le travail à faire, et en fait je
dois avouer que je n'ai pas compris comment tu déterminais "n" lorsque
tu appelais ta fonction str_readnline
En plus, je trouve la série de "if" superflue, générant du code
redondant. Et il me semble que tu gères mal les lignes de moins de 10
caractères (c'est à dire si "ligne" contient deux "n"). En fait même,
je n'ai pas bien compris ce que tu faisais d ce qui suivait le "n" que
tu venait de lire...
Un truc cloche aussi : tu ne copie pas le ' ' dans ton tableau, et
comme tu ne stocke nulle part la longueur de la chaine, je ne vois pas
trop comment tu pourrais exploitable le résultat stocké par la suite...
dont chaque ligne a un nombre variable et inconnu de caractères. Je cherche a lire ligne par ligne le fichier, et a stocker dans un tableau de chaine ces lignes. Chaque chaine du tableau doit avoir la bonne taille, pas trop grande.
En Tcl, ça prend une seule ligne pour faire ça : set list [split [read $f] 'n'] mais bon, s'il faut vraiment le faire en C... ;-)
Mon code marche pour les n-1 premières lignes, car je détecte et supprime le 'n' conservé par fgets, le problème est pour la dernière ligne... voici mon code, que me proposez vous ?
Ton code me parait trop compliqué pour le travail à faire, et en fait je dois avouer que je n'ai pas compris comment tu déterminais "n" lorsque tu appelais ta fonction str_readnline
En plus, je trouve la série de "if" superflue, générant du code redondant. Et il me semble que tu gères mal les lignes de moins de 10 caractères (c'est à dire si "ligne" contient deux "n"). En fait même, je n'ai pas bien compris ce que tu faisais d ce qui suivait le "n" que tu venait de lire...
Un truc cloche aussi : tu ne copie pas le ' ' dans ton tableau, et comme tu ne stocke nulle part la longueur de la chaine, je ne vois pas trop comment tu pourrais exploitable le résultat stocké par la suite...
Nico
Etienne de Tocqueville a présenté l'énoncé suivant :
En Tcl, ça prend une seule ligne pour faire ça : set list [split [read $f] 'n'] mais bon, s'il faut vraiment le faire en C... ;-)
ouep
Ton code me parait trop compliqué pour le travail à faire,
ah ?
et en fait je dois avouer que je n'ai pas compris comment tu déterminais "n" lorsque tu appelais ta fonction str_readnline
avec la fonction 'file_nbline(FILE *pf)'
En plus, je trouve la série de "if" superflue, générant du code redondant.
beh oui c'est ce que je voulait dire par "je trouve ma fonction pas jolie" cependant 4 cas se présentent
1/ on a lu la ligne du premier coup (< caractères) on supprime le n et on stocke le resultat, et on incrémente le compteur de ligne
2/ on a un bout de la ligne, i.e. elle fait plus de 10 carac. => on stocke ce qu'on a lu, incrémente un compteur et on repasse => le compteur ici sert a savoir si on doit allouer ou réallouer, copier ou concaténer
3/ on a toujours pas la chaine entière => on concatène se qu'on a chopé avec ce qu'on avait déjà avant, on incrémente le compteur =>on repasse
4/ on a enfin la chaine, i.e. on a repéré le n, on vire le n, concatène a ce qu'on avait déjà, et voilà
Et il me semble que tu gères mal les lignes de moins de 10 caractères (c'est à dire si "ligne" contient deux "n"). En fait même, je n'ai pas bien compris ce que tu faisais d ce qui suivait le "n" que tu venait de lire...
les lignes de moins de 10 caractères sont chopées du premier coup, fgets() va lire jusqu'au n, le reste sera lu au prochain fgets, en 1 ou plusieurs coups
Un truc cloche aussi : tu ne copie pas le ' ' dans ton tableau,
quel 0 ? mon tableau de chaine voit chacune de ses cases assignées par chacunes des chaines trouvées
et comme tu ne stocke nulle part la longueur de la chaine, je ne vois pas trop comment tu pourrais exploitable le résultat stocké par la suite...
bah justement vu que y'a les 0, un strlen() me donne la longueur de chaque chaine....
Etienne de Tocqueville a présenté l'énoncé suivant :
En Tcl, ça prend une seule ligne pour faire ça :
set list [split [read $f] 'n']
mais bon, s'il faut vraiment le faire en C... ;-)
ouep
Ton code me parait trop compliqué pour le travail à faire,
ah ?
et en fait je
dois avouer que je n'ai pas compris comment tu déterminais "n" lorsque
tu appelais ta fonction str_readnline
avec la fonction 'file_nbline(FILE *pf)'
En plus, je trouve la série de "if" superflue, générant du code
redondant.
beh oui c'est ce que je voulait dire par "je trouve ma fonction pas
jolie"
cependant 4 cas se présentent
1/ on a lu la ligne du premier coup (< caractères)
on supprime le n et on stocke le resultat, et on incrémente le
compteur de ligne
2/ on a un bout de la ligne, i.e. elle fait plus de 10 carac.
=> on stocke ce qu'on a lu, incrémente un compteur et on repasse
=> le compteur ici sert a savoir si on doit allouer ou réallouer,
copier ou concaténer
3/ on a toujours pas la chaine entière
=> on concatène se qu'on a chopé avec ce qu'on avait déjà avant, on
incrémente le compteur
=>on repasse
4/ on a enfin la chaine, i.e. on a repéré le n, on vire le n,
concatène a ce qu'on avait déjà, et voilà
Et il me semble que tu gères mal les lignes de moins de 10
caractères (c'est à dire si "ligne" contient deux "n"). En fait même,
je n'ai pas bien compris ce que tu faisais d ce qui suivait le "n" que
tu venait de lire...
les lignes de moins de 10 caractères sont chopées du premier coup,
fgets() va lire jusqu'au n, le reste sera lu au prochain fgets, en 1
ou plusieurs coups
Un truc cloche aussi : tu ne copie pas le ' ' dans ton tableau,
quel 0 ? mon tableau de chaine voit chacune de ses cases assignées par
chacunes des chaines trouvées
et
comme tu ne stocke nulle part la longueur de la chaine, je ne vois pas
trop comment tu pourrais exploitable le résultat stocké par la suite...
bah justement vu que y'a les 0, un strlen() me donne la longueur de
chaque chaine....
Etienne de Tocqueville a présenté l'énoncé suivant :
En Tcl, ça prend une seule ligne pour faire ça : set list [split [read $f] 'n'] mais bon, s'il faut vraiment le faire en C... ;-)
ouep
Ton code me parait trop compliqué pour le travail à faire,
ah ?
et en fait je dois avouer que je n'ai pas compris comment tu déterminais "n" lorsque tu appelais ta fonction str_readnline
avec la fonction 'file_nbline(FILE *pf)'
En plus, je trouve la série de "if" superflue, générant du code redondant.
beh oui c'est ce que je voulait dire par "je trouve ma fonction pas jolie" cependant 4 cas se présentent
1/ on a lu la ligne du premier coup (< caractères) on supprime le n et on stocke le resultat, et on incrémente le compteur de ligne
2/ on a un bout de la ligne, i.e. elle fait plus de 10 carac. => on stocke ce qu'on a lu, incrémente un compteur et on repasse => le compteur ici sert a savoir si on doit allouer ou réallouer, copier ou concaténer
3/ on a toujours pas la chaine entière => on concatène se qu'on a chopé avec ce qu'on avait déjà avant, on incrémente le compteur =>on repasse
4/ on a enfin la chaine, i.e. on a repéré le n, on vire le n, concatène a ce qu'on avait déjà, et voilà
Et il me semble que tu gères mal les lignes de moins de 10 caractères (c'est à dire si "ligne" contient deux "n"). En fait même, je n'ai pas bien compris ce que tu faisais d ce qui suivait le "n" que tu venait de lire...
les lignes de moins de 10 caractères sont chopées du premier coup, fgets() va lire jusqu'au n, le reste sera lu au prochain fgets, en 1 ou plusieurs coups
Un truc cloche aussi : tu ne copie pas le ' ' dans ton tableau,
quel 0 ? mon tableau de chaine voit chacune de ses cases assignées par chacunes des chaines trouvées
et comme tu ne stocke nulle part la longueur de la chaine, je ne vois pas trop comment tu pourrais exploitable le résultat stocké par la suite...
bah justement vu que y'a les 0, un strlen() me donne la longueur de chaque chaine....
et en fait je dois avouer que je n'ai pas compris comment tu déterminais "n" lorsque tu appelais ta fonction str_readnline
avec la fonction 'file_nbline(FILE *pf)'
Oh la vache ! Tu lis tout le fichier une première fois rien que pour connaitre le nombre de ligne... Tu pourrais aussi bien conter les lignes tout en lisant le fichier ! Ca serait d'ailleurs pas mal de terminer ta liste de ligne dans tbuf par un NULL pour indiquer que c'est la dernière ligne.
Et il me semble que tu gères mal les lignes de moins de 10 caractères (c'est à dire si "ligne" contient deux "n"). En fait même, je n'ai pas bien compris ce que tu faisais d ce qui suivait le "n" que tu venait de lire...
les lignes de moins de 10 caractères sont chopées du premier coup, fgets() va lire jusqu'au n, le reste sera lu au prochain fgets, en 1 ou plusieurs coups
Là, c'est moi qui me suis trompé. Il n'y a bien sur rien derrière le 'n' avec fgets. Je ne sais pas pourquoi, mais j'avais en tête que tu utilisais "read" pour lire le fichier par blocs de 10 caractères.
Un truc cloche aussi : tu ne copie pas le ' ' dans ton tableau,
quel 0 ? mon tableau de chaine voit chacune de ses cases assignées par chacunes des chaines trouvées
Ah oui j'ai compris ce qui me chiffonnait ! Effectivement tu copie le ' ' dans ton tableau, mais tu n'as pas réservé assez de place pour le mettre :
size = strlen(ligne); /*recupere la taille*/ buf = malloc(size); /*alloue un buffer de la taille qui va bien*/ strcpy(buf,ligne);
Il faut soit allouer "size+1", soit ne pas copier le "