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
Version imprimable
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
Citation:
je voudrais bien sauvegarder de manière dynamique avec malloc une chaine de caracteres
;)Code:
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é.Citation:
Envoyé par seb__
grd merci homeostasie :D
Malheureusement, il y a bon nombre de cours et même de bouquins à ne pas fréquenter en ce qui concerne le C...Citation:
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...Citation:
Envoyé par InOCamlWeTrust
Pour un club d'entraide, c'est une réponse tout à fait à propos.Citation:
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...
En tout cas, n'essaye pas de jouer à l'expert, tu n'as pas le niveau...Citation:
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.Citation:
Envoyé par Emmanuel Delahaye
Moi je ne joue pas!
OK. "Chapter and verse ?" comme on dit sur c.l.c.Citation:
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) ?Citation:
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.Citation:
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:
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!
:tagcode:
Ca fait quand même 18 ans que le C K&R est obsolète... (:oops: edit)Citation:
Envoyé par athoth
Ce qui n'est pas clair, c'est le codage. Un petit effort de logique et d'organisation et ça devient limpide :Citation:
Cet exemple montre un traitement effectué avant la fin des déclarations.Code:
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:
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!Citation:
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 ?Citation:
Ce qui n'est pas clair, c'est le codage. Un petit effort de logique et d'organisation et ça devient limpide :
Code:
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.Citation:
Envoyé par athoth
J'ai pas compris. Tu voudrais écrire le code comment ?Citation:
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...Citation:
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 typeCitation:
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!
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).Citation:
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:Citation:
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:
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.Citation:
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.
<TROLL-OU-PAS>
Pourquoi commencer avec du C K&R ? Si le C a évolué, ce n'est pas pour rien. Si tu veux continuer à rouler en voiture à vapeur, tu as le droit mais ce n'est pas une raison pour contraindre les autres à le faire.Citation:
Envoyé par athoth
Oui, c'est vrai. Et quand on apprend la médecine, on commence par apprendre à faire une bonne vieille saignée...faut commencer par les bases...Citation:
Envoyé par athoth
Et pourquoi pas ?Citation:
Envoyé par athoth
Citation:
Envoyé par athoth
Sans commentaire.Citation:
int ma_fonction(size_t size)
Citation:
Envoyé par athoth
Sans commentaire.Citation:
int ret = -1;
Citation:
Envoyé par athoth
L'optimisation, c'est au compilateur de s'en charger de nos jours. Ensuite, je veux bien voir le passage de la norme (même celle de 89 si tu veux) qui dit que l'ordre dans lequel les variables sont déclarées dans le code source présume de leur position sur la pile. Tant qu'à faire, j'accepterai aussi de voir le passage qui dit que les variables déclarées dans une fonction sont forcément sur la pile (sur toutes les architectures).Citation:
Premature optimization is the root of all evil
Parce que c'est une bonne habitude à prendre, d'autant plus quand on débute : tu comprendras l'utilité de la chose quand tu feras une erreur dans un programme et que tu auras, par exemple, deux appels à free() avec le même pointeur...Evidemment, tu ne fais peut-être pas d'erreurs...Citation:
Envoyé par athoth
Dans cette fonction, telle qu'elle est écrite, certes. Mais qui dit qu'elle névoluera jamais ?Citation:
Envoyé par athoth
Crois-le ou non mais, parfois, un bon coup de pied au c*l, ça aide plus qu'une solution toute faite à recopier.Citation:
Envoyé par athoth
Preuve ?Citation:
Envoyé par athoth
Surtout, n'hésite pas à faire gagner du temps au P.O. en essayant de l'orienter concernant sa question.
Exact. Justement, il l'a orienté vers son cours.Citation:
Envoyé par athoth
Allez-y Maître : montrez-nous la voie.Citation:
Envoyé par athoth
Je n'en mettrai pas ma main au feu : il ne précise pas, dans sa question, qu'une longueur maximale soit définie. Puisque tu es si attaché aux petits détails (ex. : l'ordre des déclarations), pourquoi ne pas participer en proposant une solution utilisant realloc() ? [1]Citation:
Envoyé par athoth
</TROLL-OU-PAS>
Et bienvenue sur Developpez.net :)
Cordialement,
DS.
[1] - Pourquoi je ne le fais pas ? Parce que je m'adapte au milieu dans lequel je me trouve.
Merci pour le lien. Dès que j'aurai un petit peu de temps je me pencherai dessus.Citation:
Envoyé par Jean-Marc.Bourguet
Tout ce que je sais de la norme ANSI vient de la deuxième édition du K&R, et je voulais seulement quelques précisions supplémentaires.
En ce qui concerne les normes, c'est sûr qu'il est toujours meilleur d'utiliser les dernières, mais le problème réside dans le fait que beaucoup de compilateurs (pour ne pas dire tous) ne les implantent pas totalement, et ça pose donc des problèmes évidents de portabilité... sauf si l'on code pour un OS précis avec un compilateur précis.
En ce qui me concerne, si je n'étais pas en train de m'éforcer à écrire du code 100% portable (donc ANSI au maximum), je serais en train de coder en C version gcc : j'aime énormément la notion de déclaration de fonction à l'intérieur d'autres fonctions, l'utilisation de blocs comme expressions ou encore les goto calculés... oui, je sais, mais je ne suis pas sectaire sur ce point-là... et puis un goto/continue bien placé permet de faire de grosses économies de code pour des programmes qui ont des branches très imbriquées et/ou complexes.
Je ne m'étais pas rendu compte qu'il s'agissait d'un lien commercial... 100$ pour un PDF... je trouve ça assez ridicule que l'on fasse payer des textes qui sont plus vieux que Mathusalem... et encore, si ils étaient imprimés, ça pourrait avoir un sens. Idem pour POSIX : il paraît que la norme est payante !Citation:
Envoyé par InOCamlWeTrust
Quelle bonne question!Citation:
Envoyé par David.Schris
Tu as tout compris à ma remarque, c'est bien!Citation:
Envoyé par David.Schris
Sans commentaire car au moins E. Delahaye a compris le propos, qui est de remplacer le 'int' par un 'char'.Citation:
Envoyé par David.Schris
Croire qu'un développeur C n'a pas à se soucier de la machine cible c'est dire au développeur du noyau Linux ou à des déveoppeurs scientifiques qu'ils n'ont pas à inclure de directive de compilation conditionnelle pour s'adapter aux différentes plate-formes.Citation:
Envoyé par David.Schris
Les compilateurs ne peuvent pas optimiser un mauvais code. Et heureusement pour nous, notre esprit est caplable de mieux faire! Donc aidons le compilateur.
Un codeur qui pense que tous les outils de la Terre lui fourniront toutes les réponses est un naïf!
Cela décèle vraiment une non maîtrise des objets manipulés! Pitoyable pour du code industriel!Citation:
Envoyé par David.Schris
C'est bien, tu es généreux, tu ajoutes du code d'avance. C'est optimum!Citation:
Envoyé par David.Schris
Oui, c'est une bonne aide. On ne cherche pas à comprendre et on n'accompagne pas. Va voir ailleurs et reviens quand tu sauras de quoi tu parles. C'est une bonne méthode ça!Citation:
Envoyé par David.Schris
Moi je ne me prend pas pour le maître du monde. Mais il y a une bonne clique qui ferait mieux de redescendre car il y a beaucoup de sotises sur ce forum!Citation:
Envoyé par David.Schris
Toi t'es un drôle!:lol:Citation:
Envoyé par David.Schris
Cordialement,
athoth.
Tu es sévère. Ce forum est, je pense, une bonne aide pour ceux qui rencontrent des problèmes dans les programmes en langage C qu'ils ont à faire dans le cadre de leurs études ou de leur boulot. Nous essayons de ne pas donner de solution 'toute cuite' car, après tout, celà n'apprend rien... et le posteur revient souvent avec un autre problème, en attendant de nouveau un programme prêt à porter.Citation:
Envoyé par athoth
Quelques contributeurs de talent participent à ce forum, et Emmanuel Delahaye est l'un d'eux. Il a son style personnel parfois un peu abrupt, certes, mais il est efficace et répond aux questions dans l'esprit du forum : l'entraide. Tu es le bienvenu pour ajouter de la valeur aux fils de discussion, mais, je t'en prie, essaie un style moins 'cassant'.
Effectivement. Ce livre est sorti en 1988. Il est basé sur les brouillons (drafts) de C89/90. Il ne tient donc pas compte des last minute changes de la version officielle.Citation:
Envoyé par InOCamlWeTrust
A noter qu'il faut aussi tenir compte de l'erratum :
http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html
Parfait. On compte sur toi pour apporter les corrections nécessaires. Personne ici ne prétend être infaillible.Citation:
Envoyé par athoth
Bonjour,
Je suis peut-être naïf mais je pense qu'il est possible de rester courtois, respectueux, etc même quand on est en désaccord avec quelqu'un. En ce sens, mon message de bienvenue n'avait rien, à mes yeux, de drôle : il était sincère. C'est pour cette raison qu'il était isolé du reste du message qui, lui, était entre des balises "<TROLL-OU-PAS>".Citation:
Envoyé par athoth
Manifestement, cette séparation entre deux propos (à l'aide de balises) n'étaient pas suffisamment claire. Par conséquent, je m'efforcerai d'éviter ce type de construction avec toi à l'avenir et m'en tiendrai à l'un ou (exclusif) l'autre de mes propos : le message de bienvenue ou (exclusif) l'imitation (cf. "OU-PAS") d'un "troll" condescendant.
Cordialement,
DS.
Citation:
Envoyé par David.Schris
+1
franchement, vous allez finir par vous faire modérer sévère en continuant sur cette voie...
@Emmanuel Delahaye: même si on délestait vos posts, vous garderiez la mention "VIP" ;)
Merci !Citation:
Envoyé par gorgonite
+1Citation:
Envoyé par Emmanuel Delahaye
Mais àmha on va attendre car le monsieur a l'air plus généreux en parole qu'en code :mrgreen: