Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Petite question simple avec un pointeur

37 réponses
Avatar
Florent Clairambault
Voila, j'ai un :
char *fich_s = "sortie.txt";

Je voudrais pouvoir en changer la valeur, j'ai esayé :
strcpy(fich_s, "sortie-auto.txt");

Ca ne marche pas... Que dois - je faire ???

Florent

7 réponses

1 2 3 4
Avatar
Emmanuel Delahaye
Charlie Gordon wrote on 07/10/04 :

Je cite pour l'exemple un bug surprenant que j'ai rencontré plusieurs fois
avec des programmeurs pourtant plus débutants :

char* fich_s = malloc(strlen("Nouvelle chaine" + 1));


J'avoue m'être fait piégé par celui-ci une fois il y a longtemps...

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"C is a sharp tool"

Avatar
Pierre Maurette
"Charlie Gordon" a écrit:

"Emmanuel Delahaye" wrote in message
news:
Florent Clairambault wrote on 06/10/04 :
En fait, un prof d'info m'a dis que c'était :
pour char* fich_s;
fich_s = (char *) malloc(strlen("Nouvelle chaine"));

Voila, j'ai l'étrange impression, que c'est pas encore gagné pour tout
le


monde la programmation...


Ce prof d'info mérite le goudron et les plumes...

pour char* fich_s = malloc(strlen("Nouvelle chaine") + 1);


Je cite pour l'exemple un bug surprenant que j'ai rencontré plusieurs fois
avec des programmeurs pourtant plus débutants :

char* fich_s = malloc(strlen("Nouvelle chaine" + 1));
Ah, oui. La bonne formule c'est:

char* fich_s = malloc(strlen("Nouvelle chaine" + 1) + 2);
--
Pierre



Avatar
Pierre Maurette
Richard Delorme a écrit:

En fait, un prof d'info m'a dis que c'était :
pour char* fich_s;
fich_s = (char *) malloc(strlen("Nouvelle chaine"));


C'est plutôt :
fich_s = malloc(strlen("Nouvelle chaine") + 1);

Le cast (char*) est inutile, sauf si tu recherches une compatibilité
C++, ce qui est mal vu par certains ici.
Il faut allouer 1 caractère de plus que la longueur de la chaine pour
stocker le '' terminal.
Le cast est aussi "utile" pour celui qui l'utilise que le

strlen("Nouvelle chaine") + 1 plutôt que 16.
Il faut dire que l'argument "ce qui est mal vu par certains ici" est
imparable. Dans le même groupe sur un autre fil, on trouve par exemple
l'usage conseillé de (void)printf("blablan") parce que sinon "on
n'attire pas (AMHA) l'attention du débutant sur le fait que printf()
retourne quelque chose...".
Le débutant qui attend quelque chose de fr.comp.lang.c doit surtout
avoir du mal à discriminer ce qui est sérieux de ce qui procède de
l'argumentite puérile.
Je suis convaincu que les plus affutés des bretteurs du groupe
n'auraient aucun mal à justifier 16 face à strlen("Nouvelle chaine") +
1, ainsi que le contraire.
--
Pierre


Avatar
Florent
C'est juste pour vous dire qu'en gros, pour répondre à ma question, il
aurait suffit de :
fich_s = (char *) malloc(strlen("Nouvelle chaine") + 1)

VOila...

Florent

--
---
Multinetworks
www.multinetworks.net

"Charlie Gordon" wrote in message
news:ck0jbd$m9l$
"Florent Clairambault" wrote in message
news:ck0h52$mtn$
En fait, un prof d'info m'a dis que c'était :
pour char* fich_s;
fich_s = (char *) malloc(strlen("Nouvelle chaine"));

Voila, j'ai l'étrange impression, que c'est pas encore gagné pour tout le
monde la programmation...



Effectivement, il manquera un octet au tableau alloué par malloc pour
contenir le NUL final de la chaine "Nouvelle chaine".
Pour cet usage, utlise:

char *fich_s = strdup("Nouvelle chaine");

Et il faut naturellement veiller à la libérer (free) à bon escient.

Chqrlie.





---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.774 / Virus Database: 521 - Release Date: 07/10/2004


Avatar
Pierre Maurette
"Florent" a écrit:

C'est juste pour vous dire qu'en gros, pour répondre à ma question, il
aurait suffit de :
fich_s = (char *) malloc(strlen("Nouvelle chaine") + 1)
Je sens une ironie bien compréhensible dans votre message. Mais je ne

suis pas certain qu'une réponse aussi simple aurait été pertinente. Il
n'est pas inutile effectivement de revenir à votre question initiale:
<cit>
Voila, j'ai un :
char *fich_s = "sortie.txt";

Je voudrais pouvoir en changer la valeur, j'ai esayé :
strcpy(fich_s, "sortie-auto.txt");

Ca ne marche pas... Que dois - je faire ???
</cit>
Vous avez un char*, donc une variable de type pointeur. strcpy() n'en
change pas la valeur, mais modifie une zone pointée. Ce n'est pas de
la sodomie de diptère, la différence est fondamentale. D'autant que
vous allez avoir à vous poser la question de la modifiabilité de la
zone pointée.
Première erreur triviale, un problème de dimension, qui provoquera une
erreur à l'exécution (à cause de l'écriture au delà de la chaine
"sortie.txt"), cette erreur se produisant souvent plus loin dans
l'éxécution du programme. Pour résoudre ce problème, vous auriez pu
penser à :
char *fich_s = "sortiexxxxx.txt";
strcpy(fich_s, "sortie-auto.txt");
Malheureusement, sur beaucoup d'implémentations, "sortiexxxxx.txt"
sera réservé en zone non modifiable, donc erreur à l'exécution (à
priori immédiate, sur strcpy()).
En revanche :
char fich_s[] = "sortiexxxxx.txt";
strcpy(fich_s, "sortie-auto.txt");
doit être sûr.

En fait, un malloc() pour votre problème est certainement inutile. Il
faut affiner l'analyse de ce que sont ""sortie-auto.txt" et
"sortie.txt", et de ce à quoi sert fich_s. Il n'y a donc pas une
réponse unique à votre question.
Si vous n'avez que ces deux chaînes à traiter, pour par exemple écrire
un fichier, il est peut-être même inutile de créer un fich_s :
if(expression)
{
/* code */
CreeFichier("sortie-auto.txt", blabla);
}
else
{
/* code */
CreeFichier("sortie.txt", blibli);
}

Sinon, vous gérez des chaînes constantes (il y a plusieurs approches
pour la manière) et vous les affectez à la demande à un char* fich_s.

A l'inverse, si vous voulez écrire des fichiers nommés sav00000.txt à
sav99999.txt (ou à partir de date et heure, c'est courant), vous aurez
besoin de générer ces noms de façon dynamique. Mais même dans ce cas,
l'utilisation du malloc() est souvent risquée, coûteuse et inutile
quand la taille de la réservation est connue à la compilation. Vous
pouvez vous contenter d'initialiser un tableau de char.

const size_t taille4 = strlen("sortie-autoX.txt") + 1;
const char* tempo1 = "sortie-auto1.txt";
char* tempo2 = "sortie-auto2.txt";
char tempo3[] = "sortie-auto3.txt";
char* tempo4 = malloc(taille4);
/* Non valable
char* tempo5 = "sortieXXXXXX.txt";
*/
char tempo5[] = "sortieXXXXXX.txt";

char* fich_s = "sortie.txt";
puts(fich_s);
fich_s = (char*)tempo1;
puts(fich_s);
fich_s = tempo2;
puts(fich_s);
fich_s = tempo3;
puts(fich_s);
fich_s = &tempo3[0];
puts(fich_s);
strcpy(tempo4, "sortie-auto4.txt"); /*(ou autre modif de la chaîne)*/
fich_s = tempo4;
puts(fich_s);

strcpy(tempo5, "sortie-auto5.txt"); /*(ou autre modif de la chaîne)*/
fich_s = tempo5;
puts(fich_s);

if(tempo4 != NULL) free(tempo4);
--
Pierre

Avatar
Charlie Gordon
"Pierre Maurette" wrote in message
news:
...
A l'inverse, si vous voulez écrire des fichiers nommés sav00000.txt à
sav99999.txt (ou à partir de date et heure, c'est courant), vous aurez
besoin de générer ces noms de façon dynamique. Mais même dans ce cas,
l'utilisation du malloc() est souvent risquée, coûteuse et inutile
quand la taille de la réservation est connue à la compilation. Vous
pouvez vous contenter d'initialiser un tableau de char.

const size_t taille4 = strlen("sortie-autoX.txt") + 1;
const char* tempo1 = "sortie-auto1.txt";
char* tempo2 = "sortie-auto2.txt";
char tempo3[] = "sortie-auto3.txt";
char* tempo4 = malloc(taille4);
/* Non valable
char* tempo5 = "sortieXXXXXX.txt";
*/
char tempo5[] = "sortieXXXXXX.txt";

char* fich_s = "sortie.txt";
puts(fich_s);
fich_s = (char*)tempo1;


très mauvais conseil, ce cast est peu recommandable, déclarer fich_s
correctement est préférable

puts(fich_s);
fich_s = tempo2;
puts(fich_s);
fich_s = tempo3;
puts(fich_s);
fich_s = &tempo3[0];


quelle différence avec fich_s = tempo3 ?

puts(fich_s);
strcpy(tempo4, "sortie-auto4.txt"); /*(ou autre modif de la chaîne)*/
fich_s = tempo4;
puts(fich_s);

strcpy(tempo5, "sortie-auto5.txt"); /*(ou autre modif de la chaîne)*/
fich_s = tempo5;
puts(fich_s);

if(tempo4 != NULL) free(tempo4);
un peu tard pour tester un pointeur qu'on a déjà déréférencé !

de plus free() devrait accepter NULL sans protester.

Là franchement, on est plus au niveau de l'ironie : l''explication est fumeuse,
et l'exemple final incompréhensible, je ne vois pas en quoi cette énumération
désordonnée aura le moindre effet pédagogique positif.

Chqrlie.

Avatar
Pierre Maurette
"Charlie Gordon" a écrit:

"Pierre Maurette" wrote in message
news:
...
[...]

Là franchement, on est plus au niveau de l'ironie : l''explication est fumeuse,
et l'exemple final incompréhensible, je ne vois pas en quoi cette énumération
désordonnée aura le moindre effet pédagogique positif.
Désolé, je n'avais pas réalisé l'importance du fait que le message

auquel je répondais était lui-même une réponse au votre. J'aurais du
suivre ma première impulsion et répondre directement au message
original.
Pour le reste, remarquez par exemple que le malloc() présent dans le
copié/collé est dans le texte qualifié de "inutile" etc.
--
Pierre

1 2 3 4