Petite Question en C

sisier

Grand Maître
Hello tout le monde,

Je me remet tout doucement au C (merci pour ton conseil de compilateur Zeb :) ).

Je me fait des petits exos. Et la, je galère avec un pointure dans une structure.
Et je ne comprend pas pourquoi.

[cpp]
typedef struct perso {
int age;
char * nom;
int sexe;
}personne;




int main(void)
{

personne perso1;

perso1.age = 15;

perso1.nom = (char *) malloc(sizeof(char)* 20);
printf("nom :");
//strcpy(perso1.nom,"alfred");
scanf("%s", perso1.nom); // perso1.nom coorespond à l'adresse --> pas besoin de &
//*(perso1.nom) = getchar();
printf("voila le nom %s", *perso1.nom); // je sais pas si c'est correcte

.....

}[/cpp]

Le programme compile bien mais il plante à l'affichage de la chaine de caractère.
Une petite aide (surtout une explication sur mon erreur ) serait la bienvenue
Merci pour votre aide :)
 

batchy

Grand Maître
pourquoi ressent tu le besoin de mettre une étoile dans ton printf ?
dans scanf comme dans printf, tu passe un pointeur vers ta chaine.

sinon j'ai du mal à croire que ''nom :'' puisse s'afficher, sans devoir user d'un fflush(stdout);
 

sisier

Grand Maître
ben dans printf, je veux la valeur de mon pointeur et pas mon adresse,non?
et dans scanf, l'inverse, l'adresse,non?

Ben, je sais pas. Il m'affiche bien mon truc. Il me met la sortie ecran par defaut.
 

ftopaz

Habitué
En fait, ce qu'il faut bien comprendre c'est quand C, les chaines de caractères n'existent pas vraiment... C'est géré comme des tableaux de char...

Quand tu ecris une chaine de caracteres avec une taille fixe :

[cpp]

char Chaine[15];

printf ("%s", Chaine);

[/cpp]

Chaine est en fait un pointeur vers le premier element du tableau de char.

Là tu peux noté que le * n'est pas utilisé... Donc il en va de même qd tu gère la taille de ta chaine avec un malloc...

Voilà, j'espere que ca t'a aidé à mieux comprendre la problematique...



 

sisier

Grand Maître


Merci pour ton aide.
En gros, si j'ai bien compris pour une chaine de caractere, il faut :
[cpp]

char Chaine[15];

printf ("%s", Chaine);

[/cpp]

Et si,je veux afficher que la premiere valeur
[cpp]

char Chaine[15];

printf ("%c", *Chaine); // ou printf ("%c", Chaine[0]);

[/cpp]

c'est ça?

(pfff .. pas bon de faire du php, apres c'est dur de se remettre au C :lol: )

 

zeb

Modérateur
Code:
char Chaine[15];
char *Chaine = malloc(15);
Ces deux lignes sont équivalentes. La différences, c'est où est allouée la mémoire (tas/pile) d'une part, et donc comment se fera la désallocation (automatique/free()).

Pour printf(), scanf(), etc, elles sont rigoureusement identiques.

Si Chaine est un pointeur, *Chaine est le contenu du pointeur.
printf("%c", .. ) attent un caractère, pas un pointeur, il affiche donc *Chaine en considérant qu'il s'agit d'un caractère.

Regarde :
Code:
int chaine[1];
*chaine = 12345;
printf("%d", *chaine);
printf("%c", *chaine);

On a vu que pointeur et tableau sont proches parents. Mais dans ton exemple, puisque Chaine est un tableau, écris Chaine[0] plutôt que *Chaine.

(Au fait, quel compilo as-tu choisi ?)
 

sisier

Grand Maître


Merci, pour ton aide.
Par contre, cette ligne :

[cpp]printf("%c", *chaine);[/cpp]

elle va affiché quoi? le caractère ASCII de 1234 (euuh ca existe?)? (au pire,j'essaierais ce soir)


Pour le compilo, j'ai choisi MinwG pour son interface simple (pas eut le courage d'utiliser cgwin et gcc).
 

zeb

Modérateur
Eh, eh. A étudier, par toi. ;)

Quelle est la taille d'un int (sizeof()) en octet ?
Quelle est la taille d'un char en octet ?
Que sont le small et le big endian ?

Enjoy :)
 

sisier

Grand Maître
euuh je dirais :
int = 2 octet.
char = 1 octet
small et big endian .. c'est pareil que gros boutiste et petit boutiste : la façon dont les octects sont lus.

Donc ca va dépendre, quel octet va etre lu en premier et va donc etre traduit si je comprend bien.

Merci :)
 

guillaumech

Expert
int sur 4 octets (en 32 bits)
char sur 2 octets (en 32 bits) ...

chaine[6] :
[fixed]
----- ['c'|'o'|'u'|'c'|'o'|'u'|'\0']
| 100
|
[100|char] ------> <=> *chaine
3
[/fixed]

*chaine est un pointeur de type char, qui pointe sur le premier élèment du tableau chaine
pour atteindre le deuxième élèment du tableau chaine avec un pointeur, tu fais *(chaine + 2) = *(chaine + sizeof(char*))
ou tu utilises la notion de tableau, comme chaine[3] = 'c', souviens toi que c'est gérer par des pointeurs derrière, comme la ligne au dessus.

Aprés tu utilses se que tu veux. Pour afficher toute ta chaine d'un coup, tu utilises %s, pour un seul caratère %c.
Si tu déclares un pointeur de type char, et que tu fais un malloc ou calloc :
[cpp]
char *pointeur;
int taille = 15;

pointeur = (*char)malloc(taille * sizeof(char));
[/cpp]
Tu pourras utiliser ton pointeur de la même manière qu'un tableau, soit pointeur[15]. Ou l'utiliser avec les pointeurs comme expliqué au dessus.

Guich
 

zeb

Modérateur
char sur 2 octets (en 32 bits) ...
sizeof(char*)
Arrête de dire n'importe quoi !

Test :
Code:
#include <stdio.h>
int main()
{
    printf("%d", sizeof(char));
    return 0;
}


Bah alors Guich :??:
 

guillaumech

Expert
Me revoilà :), oui dsl, erreur de frappe, bien sûr qu'un char est codé sur 1 octet, et non 2, toutes mes excuses :( et pour le sizeof(char*) aussi, mais la faute de frappe était évidente mon cher Zeb :) ralala (tjs aussi exigent :))
 

sisier

Grand Maître


donc
*(chaine + 1) = *(chaine + sizeof(char*))

:D

Pas grave, ca arrive (à force d'utiliser sizeof, on oublie ;) ).
je testerais tout cela ce soir.
Merci, pour votre aide ... grâce a vos exemples, ca m'aide a me remettre dans le bain :)
 

zeb

Modérateur
Non, Sisier, pas comme ça. Voilà le bon code :
*(chaine + 1) = *(chaine + sizeof(char))

sizeof(char) == 1
sizeof(n'importequoi *) == sizeof(void *) == [strike]16 bits sur un système 16 bits[/strike] (*), 32 bits sur un système 32 bits, 64 bits sur un système 64 bits, etc.


(*) Pas de Linux 16bits bien sûr :)
 

sisier

Grand Maître


Oui, je sais pas pourquoi j'avais mis ce char* . :??:

Merci :)
 
Vous devez vous inscrire ou vous connecter pour répondre ici.
Derniers messages publiés
Statistiques globales
Discussions
730 135
Messages
6 718 099
Membres
1 586 397
Dernier membre
Chachabidou
Partager cette page
Haut