Petit problème de structure / chaine de caractère - C - Programmation
Marsh Posté le 30-06-2009 à 16:06:23
strcpy sert à copier deux chaines, mais là ce n'est pas le cas ^^ j'aimerai juste que l'on m'explique clairement pourquoi je peux entrer une chaine de caractères dans jeune.nom en faisant
Code :
|
mais qu'il est impossible de le faire en faisant simplement
Code :
|
?
Et, bien entendu, s'il y a un moyen de le faire, je suis preneur ^^
merci
Marsh Posté le 30-06-2009 à 16:35:43
euuuuh ...
regarde du côté de strcpy
sinon, une chaine litérale donne un const char [] et tu dois savoir qu'on ne peut pas faire d'affectation directement entre deux tableaux
Edit : pour être sympa :
En quoi ton affectation diffère d'une copie ? Qu'est-ce que tu veux faire ?
En quoi faire un strcpy est trop compliqué ? Tu parles de quelque chose de simple, un appel de fonction ne te suffit pas ?
Marsh Posté le 30-06-2009 à 16:50:09
toyi91 a écrit : strcpy sert à copier deux chaines, mais là ce n'est pas le cas ^^ j'aimerai juste que l'on m'explique clairement pourquoi je peux entrer une chaine de caractères dans jeune.nom en faisant
|
jeune.nom est un tableau, autrement dit c'est une variable qui contient l'adresse de l'emplacement du 1er caractère de la chaine de caractère qu'il représente. Si tu lis la valeur de jeune.nom tu trouvera donc un nombre qui est l'adresse en question. Tu comprends donc que jeune.nom = "blabla" ne veut rien dire.
Tu es obligé d'utiliser strcopy ou strncpy pour copier les caractères de "blabla" dans l'emplacement indiqué par l'adresse contenue dans jeune.nom
Ne te laisse pas tromper par le cas unique où tu peux écrire jeune.nom = "blabla", c'est à dire lors de la déclaration de jeune.nom.
Marsh Posté le 30-06-2009 à 16:55:00
ngkreator a écrit : jeune.nom est un tableau, autrement dit c'est une variable qui contient l'adresse de l'emplacement du 1er caractère de la chaine de caractère qu'il représente. Si tu lis la valeur de jeune.nom tu trouvera donc un nombre qui est l'adresse en question. Tu comprends donc que jeune.nom = "blabla" ne veut rien dire. |
Précisément pasjeune.nom est un ensemble de 100 caractères contigus placés dans l'instance de Joueur, et c'est précisément pour ca qu'on ne peut pas faire pointer ce tableau sur le litéral à droite de l'affectation.
Marsh Posté le 30-06-2009 à 18:43:18
Ok ok merci pour l'explication je vais essayer tt ca ^^ bonne journée
Marsh Posté le 30-06-2009 à 19:13:03
ngkreator a écrit : Je vais ignorer ton message. |
C'est ton droit le plus absolu.
Marsh Posté le 30-06-2009 à 22:25:44
+1 avec ngkreator.
Toute affection de tableau via [] comme dans char nom[] est la même chose que de faire char* nom, ce qui montre bien qu'il affecte à la variable nom un pointeur (vers la case-mémoire du premier element du tableau)
Donc jeune.nom = "Bob" n'a aucun sens (il attend une adresse mémoire, tu lui donnes un string)
Le mieux, strcpy, ou si tu veux quelquechose qui ressemble plus à scanf : http://www.cplusplus.com/reference [...] io/sscanf/
Marsh Posté le 01-07-2009 à 02:33:15
boblenain200 a écrit : +1 avec ngkreator. |
Mais arrêtez avec ca ! Il n'attend pas une adresse mémoire ! Un tableau n'est en aucun cas une l-value. On ne peut rien lui affecter, addresse mémoire ou non. Ce n'est PAS un pointeur. Un tableau, c'est avant tout un ensemble de données contigües. Si on veut l'adresse du premier élément, on fait &tab[0]. Le comportement lors du passage en paramètre à une fonction n'a rien à voir avec le comportement qu'on obtient en déclarant un tableau sur la pile ou simplement au sein d'un structure.
Qui plus est, dans son cas, sscanf n'est pas ce qu'il attend. A la limite, je comprendrais qu'on lui propose de passer son char[100] dans sa structure en const char*, mais ici, sscanf est inutile.
Marsh Posté le 01-07-2009 à 03:53:11
ReplyMarsh Posté le 01-07-2009 à 11:55:01
ngkreator a écrit : Je vais ignorer ton message, mais pas la norme qui dit... |
chapitre 5.3 du K&R, trouve-moi un endroit où il est dit qu'un tableau est un pointeur. Déclarer un tableau revient à déclarer un groupe d'éléments. La facilité syntaxique que tu as en utilisant le nom de ton tableau comme si c'était un pointeur ne fait pas du tableau un pointeur.
Pour confirmer ce que je te dis, je t'invite à prendre l'exemple de toyi91 plus haut :
Code :
|
Je t'invite à regarder ce que te donne un sizeof sur cette structure et à comparer avec le sizeof d'une structure définie comme ca :
Code :
|
Tu verras, ca n'a rien à voir, et ce n'est pas pour rien.
De même, quand tu déclares un tableau sur la pile, tu n'alloues aucun espace pour un pointeur vers l'adresse.
Après, il en est autrement pour les arguments de fonction, mais là, ce n'est pas le sujet.
Marsh Posté le 01-07-2009 à 14:00:53
theshockwave a écrit : Un tableau n'est en aucun cas une l-value. |
Je suis fondamentalement d'accord avec ta position, excepte sur ce point precis.
Un objet de type tableau est -- comme un objet d'un type incomplet ou un objet const -- une l-value non modiable. De tels objets se convertissent dans la plupart des contextes (les exceptions etant les operandes de sizeof, &, ++, --, . et les operateurs d'assignements, certains de ces operateurs demandent des l-values modifiables comme operande et donc n'acceptent pas les tableaux parce qu'ils ne le sont pas) en un pointeur vers leur premier element. Le resultat de cette conversion n'est lui pas une l-value. Il n'est pas possible d'avoir une r-value de type tableau.
Marsh Posté le 01-07-2009 à 14:43:27
mmmh, il me semblait que pour être une l-value, il fallait avant tout pouvoir être à gauche d'une opération d'affectation (ce qui n'est donc pas directement le cas pour un tableau) et être adressables (ce qui n'est pas non plus le cas d'un tableau non plus). Autant la nuance l-value non-modifiable me parait évidente pour les const, autant pour les tableaux, ca me laisse perplexe. Tu as un peu de lecture à conseiller à ce sujet ?
Marsh Posté le 01-07-2009 à 14:56:59
C99, 6.3.2.1/1
Citation : A modifiable lvalue is an lvalue that does not have array |
Il y a une note sur une autre partie de cet alinea:
Citation : The name "lvalue" comes originally from the assignment expression E1 An obvious example of an lvalue is an identifier of an object. As a further |
C90 est fondamentalement identique meme si la formulation n'est pas la meme mot pour mot.
Marsh Posté le 01-07-2009 à 19:46:25
ngkreator a écrit : Je vais ignorer ton message. |
Tu devrais pas pourtant (ha ok posté trop vite )
Marsh Posté le 10-07-2009 à 23:21:56
ngkreator a écrit : jeune.nom est un tableau, autrement dit c'est une variable qui contient l'adresse de l'emplacement du 1er caractère de la chaine de caractère qu'il représente. |
Euh, non. Un tableau de char ne contient aucune adresse. Ce n'est pas un pointeur... Simplement, vu du compilateur, son nom a pour valeur l'adresse de son premier élément, c'est tout... Cette valeur n'est pas modifiable (non-modifiable L-value).
Citation : Si tu lis la valeur de jeune.nom tu trouvera donc un nombre qui est l'adresse en question. |
Là, on est d'accord.
Citation : Tu es obligé d'utiliser strcopy |
Un peu plus de rigueur please... strcpy() ...
Marsh Posté le 30-06-2009 à 15:31:48
Bonjour,
Je suis un débutant en C, et je bloque sur quelque chose de relativement simple.
En fait, je voudrais entrer moi même le contenu de la variable char, directement dans le code, et non en passant par un scanf.
Avec un scanf, je peux entrer le contenu de ma variable jeune.nom, il n'y a pas de problème. Mais lorsque je rentre moi même le contenu dans le code, ça ne fonctionne pas.
Ne me demandez pas l'utilité de le faire, je n'en sais rien, je voulais juste faire un test pour voir si j'avais bien compris le fonctionnement, et visiblement, j'ai raté qqc, puisque j'obtiens une erreur "incompatible types in assignements" à la compilation. Si je rentre jeune.nom[100] = "Bob", alors c'est maintenant un étrange "Son nom est AAAAÞ■" qui apparait dans la console.
Que faire? Voici le code.
Merci d'avance