Appeller une fonction [C] - C - Programmation
Marsh Posté le 24-05-2008 à 12:37:39
Le compilateur ne connait pas ta fonction au moment ou tu l'appelles (elle est définie plus bas). Il faut que tu déclares les prototypes des fonctions que tu as créé avant le main().
Puts attend un conts char*, tu lui passes un int. Normal que ca ne passe pas.
Les erreurs du compilo me semblent assez parlantes. Il serait peut être judicieux de lire un bon cours de C avant de passer à la partie code.
Marsh Posté le 24-05-2008 à 13:08:42
Merci mais ce n'était pas préciser ici :
http://c.developpez.com/cours/bern [...] node24.php
Sinon, as tu une idée pouquoi ce code plante ? Je n'ai pas d'erreur de compilateur mais le debogeur qui se lance...
Code :
|
Autre chose, je malgré tous les cours que je lis, je n'arrive pas à comprendre ce que veux dire * à coté d'un type (Ex : char et char*).
Merci
Marsh Posté le 24-05-2008 à 13:25:28
Je ne suis pas un spécialiste en C, il se peut donc que la solution que je présente ci dessous ne soit pas la meilleure.
Ta déclaration de ton char ne se fait pas comme ca.
Tu peux commencer par un :
Code :
|
Ta ligne 10 est foireuse, on ne passe pas d'un int à un const char* comme ça. J'aurais utilisé sprintf, de la façon suivante :
Code :
|
Bibliolink HFR sur le C : http://forum.hardware.fr/hfr/Progr [...] 9954_1.htm
Tu devrais te procurer en bouquin le K&R plutôt que de piocher dans des tutoriaux à droite et à gauche : tu n'as pas encore le recul (et c'est normal vu que tu ne connais pas le langage) de différencier les bonnes pratiques des mauvaises.
Dernier point pour ce qui est des variables contenant * dans la déclaration : vois au chapitre pointeurs de ton bouquin de C.
Marsh Posté le 24-05-2008 à 14:52:24
ReplyMarsh Posté le 25-05-2008 à 09:33:07
Merci mais c'est quoi la différence ? Juste l'histoire d'éviter une erreur de type OverFlow ?
Marsh Posté le 25-05-2008 à 13:42:41
Si tu veux juste afficher le nombre c'est quand même plus simple d'utiliser printf() :
Code :
|
Le problème avec snprintf() c'est que c'est du C99 donc pas super portable. Sous Windows il y a _snprintf() mais elle n'a pas l'air d'ajouter le '\0' quand le buffer déborde. Au pire il y a StringCbPrintf().
Marsh Posté le 25-05-2008 à 13:52:37
Merci c'est mieux mais qu'est ce que ca veut dire : %d\n ?
Marsh Posté le 25-05-2008 à 14:12:42
%d c'est pour dire de prendre le prochain argument et de l'afficher en tant qu'int, le \n c'est pour ajouter un saut de ligne. On en parle forcément à un moment dans le tutoriel que tu lis.
Marsh Posté le 25-05-2008 à 15:25:22
dap++ a écrit : Le problème avec snprintf() c'est que c'est du C99 donc pas super portable. |
C'est faux.
Marsh Posté le 25-05-2008 à 21:10:02
ReplyMarsh Posté le 25-05-2008 à 21:59:14
Taz a écrit : C'est faux. |
ah bon ?
Je dis aussi que snprintf c'est du C99 et une extension de gcc devenue un standard, mais un compilo C ANSI peut très bien ne pas la proposer, et c'est le cas de Visual c++.
Marsh Posté le 25-05-2008 à 22:38:15
_snprintf existe dans Visual C++ 2005 mais est "deprecated" pour une version plus "secure"
int _snprintf_s( char *buffer, size_t sizeOfBuffer, size_t count, const char *format [, argument] ... );
Marsh Posté le 25-05-2008 à 22:42:55
Taz a écrit : C'est faux. |
Tu connais un runtime C99 gratuit pour Windows ?
Marsh Posté le 25-05-2008 à 23:47:50
jesus_christ a écrit : |
Faux pas déconner, on est 10 après.
Marsh Posté le 25-05-2008 à 23:49:02
Trap D a écrit : _snprintf existe dans Visual C++ 2005 mais est "deprecated" pour une version plus "secure" |
J'ai jamais compris cette culture ouinouin de l'_
Marsh Posté le 26-05-2008 à 00:13:20
Taz a écrit : J'ai jamais compris cette culture ouinouin de l'_ |
Ouais, ou cette manie de conseiller des fonctions non-standard soit disant plus "secure", ou comment reléléguer les tares de conception de Windows sur les standards (et accessoirement obliger les gens à utiliser des APIs propres à Microsoft, histoire qu'ils évitent d'aller vers d'autres paturages).
Sinon, snprintf existe bien sur Windows, mais ne rajoute pas ce foutu 0 si ça déborde (peut-être avec une mscvrt.dll récente ils ont enfin corrigé ça, mais pas avec celle venant en standard avec Windows XP).
J'imagine que cette fonction à du être rajouté avant le C99, avec un comportement à la Microsoft, et que maintenant une tétrachiée de programmeurs incompétents doivent dépendre de cette "fonctionnalité". Et comme Microsoft préfère rajouter des hacks de gros porc plutôt que de briser la moindre "compatibilité", ça nous donne plein d'"extensions" de ce genre ...
Marsh Posté le 26-05-2008 à 00:25:02
tpierron a écrit : ... snprintf existe bien sur Windows, mais ne rajoute pas ce foutu 0 si ça déborde ... |
ce snprinf se comporte comme strncpy, donc un comportement "à la C" qui a un sens dans certains cas (qd tu mets ta chaine dans un buffer de taille fixe, comme c'est souvent le cas avec l'utilisation de strncpy ou snprintf), t'as pas envie de gaspiller un octet avec le 0 à la fin puisque tu connais la taille max de la chaine.
Et crosoft a raison de ne pas casser la retrocompatibilité, moi ça m'emmerderai d'avoir un comportement différent selon la version de la crt.
Leur version de _snprintf fait ce que dit la doc :
http://msdn.microsoft.com/en-us/li [...] S.71).aspx
après celui qui lit pas la doc, il assume.
Marsh Posté le 26-05-2008 à 00:26:43
Taz a écrit : |
et le mec qui a codé son propre snprintf ou qui l'a importé depuis une lib d'extension, il a pas envie de se tapper un conflit au link.
Tu te demandes alors pas aussi pourquoi en C99 le type booléen natif c'est _Bool et pas bool ?
C'est pour la même raison.
Marsh Posté le 26-05-2008 à 19:34:32
jesus_christ a écrit : |
Wow, tu dois trop bosser avec Windows et pas te rendre compte à quel point c'est mal foutu et insidieux ce genre d'approche.
Qu'ils ne réussissent pas du premier coup, je peux le comprendre. Qu'ils veulent garder la compabitilié binaire, je veux bien aussi, c'est le fond de commerce de Windows après tout.
Mais qu'ils s'entêtent à imposer leur solutions merdiques, c'est gerbant. En l'occurence une bonne approche aurait de ce conformer à ce que dit la norme C99 : tu rajoutes toujours ce foutu 0 et tu retournes le nombre de caractères écrit (ou ce qu'on aurait du écrire). Pour les quelques programmes mal torché, prévoir un mode de compatibilité, style :
#define JE_SUIS_TROP_CON_POUR_MODIFIER_MON_PROGRAMME.
Maintenant qu'en interne snprintf (la version correcte) s'appelle _snprintf, _snprintf_s, _snprintf_putain_cette_fois_cest_la_bonne() au gré des errements, on s'en fout, du moment que dans un programme se prétandant conforme ISO C99, il y ait écrit snprintf(), qui se comporte comme expliqué dans tout bon bouquin. Ah ouais, mais là, on pourrait changer plus facilement de crémerie.
Alors pour Microsoft, il faut lire les MSDN pour distinguer ce qui est standard de ce qui ne l'est pas pas complètement. Rajouter quelques hacks, quelques wrapper, et croiser les doigts pour être sûr de n'avoir rien oublié.
Marsh Posté le 28-05-2008 à 22:58:11
Visual C++ n'est pas et n'a jamais été un compilateur C99.
Le _snprintf de Visaul existait déjà avant le C99, et je trouve logique la façon dont ils l'ont implémenté vis à vis du comportement des fonctions existantes à l'époque, comme strncpy.
Marsh Posté le 29-05-2008 à 03:11:12
Sans doute, sauf qu'il utilise les mêmes noms que le C99, ça marche presque pareil, ça pourrait presque te faire croire qu'ils l'ont implémenté comme le C99 (ça ne fait après tout "que" 9 ans qu'elle existe cette norme). Sauf que le petit truc qui n'est pas pareil peut te péter méchamment à la gueule. Et qui plus est ce n'est pas Visual C++ le problème, mais la msvcrt.dll. Il n'y a pas que Visual C qui l'utilise, MinGW aussi, et sans doute d'autres compilateurs aussi.
Marsh Posté le 29-05-2008 à 22:14:50
bien vu pour la DLL
Pour le nom, ils l'ont choisi avant 1999 ou toutes les fonctions avec limitation du nombre total de caractères avait ce préfixe n, comme celles qui prennent un va_args en parametres qui ont un préffixe v.
A la limite, je trouve même la vraie sprintf du C99 mal conçue car
1) pas cohérente avec l'existant en C 89
2) ne permet pas de ne PAS mettre le '\0'. Celui qui veut le mettre peut toujours faire un sprintf avec n-1 caractères (donc caractères de 0 à n-2) et mettre le caractère n-1 à zero à la main dans son buffer de taille n.
Quand à l'age du C99, c'est juste que c'était pas une extention très attendue, et ses grandes nouveautés (macro variadic, fonctions n/v, type bool et type complex...) sont déjà présentes dans les compilo C 89 récents.
J'espère que le C++ 0x sera vite implémenté coté compilos, lui.
ah, type auto
Marsh Posté le 30-05-2008 à 16:38:36
tpierron a écrit : Ouais, ou cette manie de conseiller des fonctions non-standard soit disant plus "secure", ou comment reléléguer les tares de conception de Windows sur les standards (et accessoirement obliger les gens à utiliser des APIs propres à Microsoft, histoire qu'ils évitent d'aller vers d'autres paturages). |
tpierron a écrit : Sinon, snprintf existe bien sur Windows, mais ne rajoute pas ce foutu 0 si ça déborde (peut-être avec une mscvrt.dll récente ils ont enfin corrigé ça, mais pas avec celle venant en standard avec Windows XP). |
Non snprintf() n'existe pas dans le runtime de Microsoft.
jesus_christ a écrit : Leur version de _snprintf fait ce que dit la doc : |
Mention spéciale à MinGW qui fait semblant d'implémenter snprintf() alors qu'il se contente d'appeler _snprinf().
tpierron a écrit : Et qui plus est ce n'est pas Visual C++ le problème, mais la msvcrt.dll. Il n'y a pas que Visual C qui l'utilise, MinGW aussi, et sans doute d'autres compilateurs aussi. |
Visual C++ utilise les versions mises à jour du runtime. MinGW utilise (par défaut) juste la vieille msvcrt.dll (elle date de 2004 chez moi), je ne sais pas si ça peut être changé.
Marsh Posté le 05-06-2008 à 16:44:50
dap++ a écrit : Non snprintf() n'existe pas dans le runtime de Microsoft. |
Oups exact, c'est bien _snprintf qui est appelé, même avec la dernière version de MinGW.
dap++ a écrit : |
Ouais, mais ce ne sont pas des dll livrés en standard. MinGW n'utilise que les libs de base de Windows et je doute les versions récentes de cette lib change quoi que ce soit. Elles font ce qui est marqué dans la doc.
J'ai l'impression que c'est encore plus le bordel que ce que j'imaginais, des hacks pourris version Microsoft, alors qu'avec un minimum d'effort ils auraient pu éviter ça facilement. Parce que, question bête : sous Visual C++, snprintf est lié à quoi?
Je doute que ça utilise une version standard : à moins d'une API planqué (ça serait un coup de pute pour MinGW), pas une version statique (ça me parait difficile, le code de retour est inutilisable si le buffer est trop petit), une version plus récente de la dll ne changerait rien non plus, puisque la fonction doit faire ce qui est décrit dans la doc. Donc j'ai l'impression que Visual C++ est au même niveau (je dis ça, mais je n'utilise pas ce compilo). En tous les cas s'il a une version standard, j'aimerais bien savoir comment il y arrive (sans reprogrammer snprintf bien sûr).
Marsh Posté le 24-05-2008 à 12:01:44
Salut,
Je tiens à préciser que je viens juste de découvrir ce langage et que je suis habitué à coder en vb.net
Voici mon code :
A la ligne 6 et 7 j'ai trois erreurs du compilo :
In function `int main()':|
|6|error: `test' was not declared in this scope|
|7|error: invalid conversion from `int' to `const char*'|
|7|error: initializing argument 1 of `int puts(const char*)'|
||=== Build finished: 3 errors, 0 warnings ===|
Etant newbie, je ne comprends pas les erreurs surtout que mon appelle de fonction a l'air correcte. Ensuite pour afficher le résultat, j'en suis sur que c'est faux
merci à tous
---------------
http://www.tutoworld.com - http://www.tutoworld.com/forum