Bonjour, je débute en C, je voudrais bien sauvegarder de manière dynamique avec malloc une chaine de caracteres que l'utilisateur entrera, quelqu'un peut il m'aider?C'est pas bien sorcier je suppose mais bon
Bonjour, je débute en C, je voudrais bien sauvegarder de manière dynamique avec malloc une chaine de caracteres que l'utilisateur entrera, quelqu'un peut il m'aider?C'est pas bien sorcier je suppose mais bon
je voudrais bien sauvegarder de manière dynamique avec malloc une chaine de caracteres
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 unsigned int taille_chaine = 100; char *chaine = malloc(sizeof(*chaine) * taille_chaine); if (chaine == NULL) { /*erreur d'allocation mémoire*/ /*traitement ou non de l'erreur*/ } /*Utilisation de ta chaine*/ ... /*Libération de la mémoire allouée*/ free(chaine);![]()
C'est effectivement pas sorcier du tout, alors soit tu sais le faire, et alors fait le, soit tu ne sais pas et tu relis ton cours de C sur l'allocation dynamique. Dans les deux cas, c'est à toi d'écrire le code et à nous de vérifier ce que tu as posté.Envoyé par seb__
Malheureusement, il y a bon nombre de cours et même de bouquins à ne pas fréquenter en ce qui concerne le C...Envoyé par Emmanuel Delahaye
Dernièrement vu à Supélec (oui, c'est bien la grande école) : une matrice déclarée de façon automatique ou via un vecteur de pointeurs auxquels on affecte une adresse retournée par malloc, c'est la même chose.
Cool.
Ca ne vous fait pas froid dans le dos savoir que ce sont ces mêmes gens qui forment les ingénieurs de demain ? Moi, ça me laisse sans voix !
C'est une des raisons qui me pousse à devenir formateur...Envoyé par InOCamlWeTrust
Pour un club d'entraide, c'est une réponse tout à fait à propos.Envoyé par Emmanuel Delahaye
Je te déconseille vivement de devenir formateur car les élèves vont fuir tes cours et perdre leur temps.
Le rôle d'un "expert" est avant tout d'orienter les non experts...
J'en ai déjà vu beaucoup des "experts"... Tu es un bon exemple à ne pas suivre.
POUR LA QUESTION:
le bout de code donne la réponse mais:
char *chaine = malloc... n'est pas une ligne de C. En effet, en C seule une affectation de constante peut être faite avec une déclaration (comme l'exemple le montre avec int taille_chaine = 100; ). Pas d'appel de fonction durant une déclaration! Certains compilateurs n'accepteront pas.
Si ED était formateur, ce serait lui qui le donnerait, le cours sur l'allocation dynamique.
Donc, je ne vois pas où est le problème...
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
En tout cas, n'essaye pas de jouer à l'expert, tu n'as pas le niveau...Envoyé par athoth
Ce code est tout à fait légal, car la variable n'est pas statique.
Ta remarque concerne les définitions de données statiques où il n'est effectivement pas possible d'appeler une fonction.
Pour ta gouverne, sache que 'titre' d'expert sur ce forum est donné par le logiciel en relation avec le nombre de posts conservés. C'est tout. Si l'admin décide d'effacer mes posts, je redeviens 'invité occasionnel' et ça ne m'empêchera pas de dormir...
Le C ansi est très clair sur ce point. Pas d'appel de fonction lors d'une déclaration.Envoyé par Emmanuel Delahaye
Moi je ne joue pas!
OK. "Chapter and verse ?" comme on dit sur c.l.c.Envoyé par athoth
http://www.open-std.org/jtc1/sc22/wg...docs/n1124.pdf
Une petite question tant que l'on est dans le domaine des normes et autres : est-ce que quelqu'un connaît un lien vers le texte de la norme ANSI (C89) ? Mes recherches pour le trouver n'ont malheureusement pas été fructueuses.
Merci.
Je viens de publier le lien vers la norme actuelle du C. Tu tiens explicitement au texte ancien (ANSI C89 ou ISO-C90) ?Envoyé par InOCamlWeTrust
Dans la mesure où beaucoup de compilateurs en service se réfèrent à cette norme, ça peut se comprendre.
Par contre, malheureusement, je ne crois pas que ce document soit encore disponible, et mon DD qui le contenait peut être, bien que tout neuf, est crashé...
Ce que je recherche, c'est bien le texte de la norme originelle ANSI-C89. Les autres, je ne m'y intéresse pas encore, étant donné que les compilateurs n'implantent pas la norme ISO-C99 en entier, voire pas du tout...
Je suis allé sur le site de l'ANSI, mais je n'ai rien trouvé... ou alors j'ai dû mal chercher !
Il est un peu délicat à trouver, il faut prendre la version australienne
http://webstore.ansi.org/ansidocstor...AS+3955%2D1991
Alternativement, tu cherches le seul bouquin de Herbert Schildt qu'un programmeur C qui se respecte avoue posséder:
http://www.amazon.com/gp/offer-listi...e=UTF8&s=books
Je concède que la norme autorise les initialisateurs de type fonction (expression retournant un type compatible) avec l'objet de la déclaration.Envoyé par Emmanuel Delahaye
Mais le draft de présentation en 1988 du C "conventionnel" (dixit Ritchie) donne avant tout:
type-de-retour nom-de-fonction (déclaration des paramètres éventuelles)
{
déclarations
instructions
}
Or l'appelle d'une fonction ou une définition non constante comme initialisateur d'un objet en cours de déclaration contredit la "forme conventionnelle" du C.Cet exemple montre un traitement effectué avant la fin des déclarations.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 int ma_fonction(size_t size) { void *m = malloc(size); int ret; ret = -1; if(m != NULL) { /* Code */ free(m); ret = 0; } return ret; }
Le compilo donnera un programme où le malloc est realisé après la réservation des objets déclarés dans la pile, mais à la lecture de ce code C, ce n'est pas clair (surtout pour un novice).
D'ailleurs dans l'apprentissage du C, on ne donne pas d'exemple où se trouve des initialisateurs non constants. En tout cas, dans "Le langage C" par Kernighan et Ritchie il n'y en a pas!
![]()
Ca fait quand même 18 ans que le C K&R est obsolète... (Envoyé par athoth
edit)
Ce qui n'est pas clair, c'est le codage. Un petit effort de logique et d'organisation et ça devient limpide :Cet exemple montre un traitement effectué avant la fin des déclarations.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 int ma_fonction(size_t size) { void *m = malloc(size); int ret; ret = -1; if(m != NULL) { /* Code */ free(m); ret = 0; } return ret; }
Le compilo donnera un programme où le malloc est realisé après la réservation des objets déclarés dans la pile, mais à la lecture de ce code C, ce n'est pas clair (surtout pour un novice).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 int ma_fonction(size_t size) { int ret = -1; void *m = malloc(size); if (m != NULL) { /* Code */ free(m), m = NULL; ret = 0; } return ret; }
18 ans ça sera déjà bien! Le C avec toutes les extensions de langage n'est plus tout à fait du C d'origine, certe! Mais si on donne des renseignements à un débutant autant commencer par la forme classiquement définie et donner les formes plus subtiles ensuite!Envoyé par Emmanuel Delahaye
Quant on apprend la physique, on ne commence pas par la mécanique quantique ou la théorie M.
1) La fonction possède peu de déclaration. Tu forces l'exéctution des initialisateurs à la fin des déclarations... alors pourquoi les garder dans les déclaration ?Ce qui n'est pas clair, c'est le codage. Un petit effort de logique et d'organisation et ça devient limpide :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 int ma_fonction(size_t size) { int ret = -1; void *m = malloc(size); if (m != NULL) { /* Code */ free(m), m = NULL; ret = 0; } return ret; }
De plus, si la fonction renvoie un char et donc que ret est un char, avec ton ordre de déclaration tu gaspilles de l'espace dans la pile car les objets sont alignés!
2) Je ne vois pas à quoi sert l'affectation de m à NULL !? Le pointeur n'est de toute façon plus accessible en sortie de fonction!
L'analogie ne tient pas. Il n'y a aucun intérêt à enseigner le C des années 70... On devrait plutôt enseigner le C99, mais il se trouve que l'immense majorité des compilateurs installés un peu partout est compatible C90. Il est donc logique que ce soit ce C là qui fasse référence, même aujourd'hui.Envoyé par athoth
J'ai pas compris. Tu voudrais écrire le code comment ?1) La fonction possède peu de déclaration. Tu forces l'exéctution des initialisateurs à la fin des déclarations... alors pourquoi les garder dans les déclaration ?
Tu as cherché longtemps pour trouver cet argument discutable ? La mémoire automatique est généralement organisée en int. Alors on ne perd rien du tout. Pour les détails, désassembler...De plus, si la fonction renvoie un char et donc que ret est un char, avec ton ordre de déclaration tu gaspilles de l'espace dans la pile car les objets sont alignés!
D'autre part (et c'est probablement lié), tout argument ou retour de type char est promu en int. Le type char ne sert donc à rien ici.
A préparer une vérification de type2) Je ne vois pas à quoi sert l'affectation de m à NULL !? Le pointeur n'est de toute façon plus accessible en sortie de fonction!
assert (m == NULL); en fin de bloc.
Il est en effet recommandé qu'un pointeur ait pour valeur soit NULL (invalide), soit une valeur valide. Donc, après un free(), on doit rapidement repositioner le pointeur sur NULL.
Bien sûr, ce n'est pas obligatoire. C'est juste une bonne pratique professionnelle.
Le C des années 70 ne s'écrivait pas du tout comme cela et d'ailleurs tant mieux si ce point a changé! Mais pour assimiler le plus facilement une nouveauté, mieux vaut se baser sur une forme classique (donc pas forcément antique).Envoyé par Emmanuel Delahaye
Je ne trouve pas mon argument discutable. Les objets de la piles sont alignés sur des int... sauf si les objets qui se suivent peut être groupés dans un int, exemple:Envoyé par Emmanuel Delahaye
L'organisation de la pile n'est pas gérée automatiquement par le compilo et donc ma_fonction2 consommera plus que ma_fonction1. En recursion c'est problèmatique!
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 void ma_fonction1(void) { void *m1; // +4 void *m2; // +8 long n1; // +12 long n2; // +16 short s1; // +18 short s2; //+20 char c1; // +21 char c2; // +22 char c3; // +23 char c4; // +24 /* Code */ } void ma_fonction2(void) { char c1;// +4 car n1 ne peut compléter au même endroit long n1; // +8 short s1; // +12 long n2; // +16 char c2; // +20 void *m1; // +24 char c3; // +28 void *m2; // +32 short s2; // +34 char c4; // +35 soit + 36 car par la suite le compilo complète envue d'éventuel call /* Code */ }
L'alignement en vue du 'return' ne change rien à cela.
La vérification par 'assert' est utile avec un code en mode debug. Pour les mises au point, je veux bien mais cela montre tout de même une potentielle non maitrise de la valeur des pointeurs. C'est très ennuyeux dans le monde industriel.Envoyé par Emmanuel Delahaye
Parfois la bonne pratique mène à un relachement.
De toute façon, 'assert' signale un état mais pas sa cause. Le code ne sera pas plus maitrisé!
Dans notre cas d'école c'est de toute façon hors de propos.
Partager