je veux ecrire un petit prog de calcul sur des coordonnees 3D.
j'ai donc uns structure de ce type :
typedef struct
{
short x;
short y;
short z;
} point;
/* coordonnees pour chaque point */
point *p ;
point liste[NPI];
jusque la tout tout va bien
mais a l'execution d'un test (avant d'ecrire la suite)
je fais ca comme test precisement :
/* 1ere compile pour tester le mode de saisie */
for(i=0;i<NPI;i++)
{
scanf(" %d %d %d", &liste[i].x, &liste[i].y, &liste[i].z);
/* copie l'entr� dans la liste */
}
for(i=0;i<NPI;i++)
{
printf("\n %d %d %d", liste[i].x, liste[i].y, liste[i].z);
}
je rentre que des
1 2 3
4 5 6
7 8 9
10 11 12
et ainsi de suite
mais a la relecture (la seconde boucle )
le retour est
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
pourquoi donc ?
le scanf ne marche pas ?
merci de m'eclairer sur cette erreur de coding...
# Parentheses ?
Posté par Ph Husson (site web personnel) . Évalué à 2.
Par reflexe je mets souvent des () on peut me dire que c'est inutile m'enfin au moins je suis sur de ce que fait le compilo ...
[^] # Re: Parentheses ?
Posté par frp31 . Évalué à 1.
j'utilise GCC comme compilo donc ANSI alors les parentheses forcees comme ca je me disais bien que ca servirai pas...mais il y avait de l'idee :)
# short
Posté par Pascal Terjan (site web personnel) . Évalué à 2.
# %hd
Posté par netsurfeur . Évalué à 2.
[^] # Re: %hd
Posté par frp31 . Évalué à 1.
j'avais completement oublie ce detail tellement habitue a utiliser du long int...
:)
je teste de suite !!!
# Bizarre
Posté par lolop (site web personnel) . Évalué à 2.
Mais quand même, vu la doc, essaie avec d'autres formats...
Cf doc de scanf:
[laurent@litchi badscan]$ gcc --version
gcc-4.1.1 (GCC) 4.1.1 20060724 (prerelease) (4.1.1-3mdk)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
[laurent@litchi badscan]$ ./a.out
1 2 3
4 5 6
7 8 9
10 11 12
1 2 3
4 5 6
7 8 9
10 11 12
Votez les 30 juin et 7 juillet, en connaissance de cause. http://www.pointal.net/VotesDeputesRN
[^] # Re: Bizarre
Posté par frp31 . Évalué à 1.
(je testai sur le macppc avec une vielle gcc 3.3.5 sous debian avec un powerbook
sur le pc j'ai gcc 4.0.2 et oui ca passe...
mais bon vu que le programme tournera sur des machines de collections (non PC)
sur mac ppc mac68K et autres rognes je prefere forcer le format au cas ou...
sinon je pourrai tjrs cross compiler !
MERCI pour l'aide !!!!!
[^] # Re: Bizarre
Posté par daggett . Évalué à 1.
Donc quand ton scanf ecrit dans ce qu'il croit etre un pointeur sur int, sur x86 il va écrire "octet 1 octet 2 octet 3 octet 4", qui vont ecrire sur "x" et "y". Sur power il va ecrire "octet 4 octet 3 octet 2 octet 1".
Puis il va ecrire sur "y et z", puis sur "z et au dela".
Sur tes tests avec de petites valeurs, octets 2-4 valent 0, et seul l'octet 1 contient entre 1 et 12.
Avec les écrasements successifs des "%d %d %d" tu vas écrire dans x y z:
"octet 1 octet 2 , 1 - 2, 1-2" sous x86 (qui a donc la chance de donner la meme valeur si elle etait < 65535) et "3-4, 3-4, 3-4" sous power (donc que des octets nuls)
Si vous faisiez des tests avec comme valeur "65536", sous x86 la sortie ne donnerait que des 0, et sous power, que des 1.
[^] # Re: Bizarre
Posté par alf . Évalué à 2.
Ce n'est pas parce que ton programe est tombé en marche qu'il est correct ;)
[^] # Re: Bizarre
Posté par lolop (site web personnel) . Évalué à 2.
Sauf que là je ne comprend pas pourquoi c'est "tombé en marche" :-)
Faudrais désassembler, tout ça... autre chose à faire.
Votez les 30 juin et 7 juillet, en connaissance de cause. http://www.pointal.net/VotesDeputesRN
[^] # Re: Bizarre
Posté par alf . Évalué à 3.
Si ton int fait vraiment 4 octets, je soupçonne très fortement que, en raison de l'alignement mémoire de la structure, un des trois octets nuls est tombé sur l'octet de poids fort du short et les deux autres octets sont tombés dans la zone de bourrage.
Quoi qu'il en soit, il s'agit très sûrement d'un comportement indéfini (je n'ai pas vérifié la norme) qui tombe en marche par miracle de l'alignement et de l'endianness.
Il est aussi possible que sizeof(short) == sizeof(int) et alors on ne se pose même plus de question...
[^] # Re: Bizarre
Posté par lolop (site web personnel) . Évalué à 2.
Pour ça, avec le GCC que j'ai testé, c'est sûr que non, j'ai vérifié hier soir en printfant les sizeof de int et de short.
Par contre, une optimisation due à l'alignement des short tous les 4 octets... ça expliquerais bien la chose.
Votez les 30 juin et 7 juillet, en connaissance de cause. http://www.pointal.net/VotesDeputesRN
# Et avec gcc...
Posté par lolop (site web personnel) . Évalué à 4.
Votez les 30 juin et 7 juillet, en connaissance de cause. http://www.pointal.net/VotesDeputesRN
# scanf ?
Posté par alf . Évalué à 3.
L'utilisation "propre" de scanf est très difficile, car les traitements d'erreur ne sont pas simples. Si une entrée ne respecte pas le bon format, alors scanf s'arrête sans "consommer" l'entrée standard. Si tu boucles sans vérifier le bon fonctionnement de scanf, et sans "consomer" toi-même l'entrée standard quand il y a une erreur, tu causes une boucle infinie de ton programme.
La meilleure solution est de lire une ligne complète à la fois, puis de la traiter en mémoire. Pour celà, le mieux est d'utiliser une fonction qui encapsule fgets, comme ggets ( http://cbfalconer.home.att.net/download/index.htm ), et de traiter la chaîne de caractères résultante avec sscanf (ou strto*).
Mais que tu utilises scanf ou sscanf (ou strto*), il est nécessaire de tester le bon fonctionnement de ces fonctions. Les *scanf renvoient le nombre de conversions effectuées avec succès (et strto* possède un argument spécifique). Tu dois donc effectuer le test :
if (scanf(" %d %d %d", &liste[i].x, &liste[i].y, &liste[i].z) == 3)
{
/* traitement normal */
}
else
{
/* erreur ! */
}
Pour plus de détails, se référer à la FAQ de comp.lang.c, question 12.20 : http://c-faq.com/stdio/scanfprobs.html .
De plus :
La sortie standard peut être bufferisée, donc place un "\n" en fin de la chaîne de format de printf, ou appelle fflush(stdout) pour vider l'éventuel tampon.
PS: pendant que j'y suis, gcc -Wall -Wextra -std=<ton choix> -pedantic est ton ami (remplacer -Wextra par -W pour les versions inférieures à 4, je crois).
[^] # Re: scanf ?
Posté par Krunch (site web personnel) . Évalué à 2.
pertinent adj. Approprié : qui se rapporte exactement à ce dont il est question.
[^] # Re: scanf ?
Posté par alf . Évalué à 2.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.