logo Homepage
Pages: [1]
  Imprimer  
Auteur Fil de discussion: [Résolu] [C++] Problème avec l'élement 0 d'un tableau.  (Lu 3802 fois)
mogg41

Profil challenge

Classement : 449/54286

Membre Senior
****
Hors ligne Hors ligne
Messages: 267

Mogg41 pour vous aider!


Voir le profil
« le: 16 Août 2008 à 23:22:39 »

Bonjour à tous.

En codant un programme pour résoudre l'épreuve nos chères configs, il m'est arrivé un truc étrange avec l'élément 0 d'un tableau d'entier.

Prenons un bout de code tout simple:
Code:
FILE *test = fopen("prix.txt","r");
int RAM[8];
fscanf(test,"%d",RAM[0]);

Lorsque je compile et exécute j'ai le droit à une belle erreur! Alors que le code:
Code:
FILE *test = fopen("prix.txt","r");
int RAM[8];
fscanf(test,"%d",RAM[1])
fonctionne normalement. J'ai donc pensé qu'il n'y avait pas d'élément 0 en C++ (je viens de passer récemment du C au C++) mais j'ai vérifié et il existe bel et bien.

Je vérifie donc avec le bout de code suivant:
Code:
int RAM[8];
RAM[0]=1;
printf("L'element 0 vaut %d.",RAM[0]);
Et j'obtiens bien 1.

J'ai cherché veinement sur google. Je précise que j'utilise windows XP et dev C++. Cela ne m'empêche pas de continuer mon programme mais j'aimerai bien avoir une explication ou un bout de piste.

Merci de votre lecture.

Mogg
« Dernière édition: 17 Août 2008 à 11:49:42 par mogg41 » Journalisée

"Il ne savait pas que c'était impossible alors il l'a fait." Mark Twain
Slack

Profil challenge

Classement : 624/54286

Néophyte
*
Hors ligne Hors ligne
Messages: 44


Voir le profil WWW
« #1 le: 17 Août 2008 à 00:22:13 »

Hum, RTFM...
 
Journalisée
simpsonmaniac

Profil challenge

Classement : 567/54286

Membre Junior
**
Hors ligne Hors ligne
Messages: 60

Essayer, c'est le meilleur moyen de se planter...


Voir le profil
« #2 le: 17 Août 2008 à 00:55:07 »

euh je ne suis pas sûr mais il me semble que le nom du tableau correspond à sa première case
Code:
FILE *test = fopen("prix.txt", "r");
int RAM[8];
fscanf(test, "%d", RAM)
Journalisée

C:/dos
C:/dos/run
run/dos/run
sirk390
Beta testeur

Profil challenge

Classement : 1/54286

Membre Junior
*
Hors ligne Hors ligne
Messages: 92

Sirk390


Voir le profil WWW
« #3 le: 17 Août 2008 à 02:24:42 »

Oui, les deux sont faux et ce n'est pas en rapport avec l'élément 0 ou 1.

Il faut passer le paramètre par adresse et non par valeur (sinon fscanf ne pourra rien modifier).
Dans ton example tu envoye le contenu (non initialisé) de RAM[0] à fscanf au lieu de l'adresse à laquelle il pourra sauver le résultat (RAM ou &RAM c'est pareil). il faut un int* au lieu d'un int.
Donc pour la première case du tableau ( RAM[0] ) :
Code:
fscanf(test, "%d", RAM)
ou pour la deuxieme  ( RAM[1] )
Code:
fscanf(test, "%d", RAM + 1)
« Dernière édition: 17 Août 2008 à 02:32:17 par sirk390 » Journalisée

Trop cool NC!
S3cur3D

Profil challenge

Classement : 201/54286

Néophyte
*
Hors ligne Hors ligne
Messages: 9


Voir le profil WWW
« #4 le: 17 Août 2008 à 02:41:04 »

Salut,

Si je ne me trompe pas, tu devrais avoir quelquechose du style "expects int* but type is int".
Donc, c'est un warning et non pas une erreur (ce qui permet à la compilation de continuer son cours).
Comme d'habitude, les messages sont assez explicites. Les fonctions de la famille scanf attendent toujours un pointeur en argument afin de ranger la valeur obtenue à l'adresse pointée. Dans ton cas, tu donnes RAM[0] qui référence directement l'entier se trouvant à l'offset 0. Par conséquent, mettre simplement RAM (qui référence l'adresse de début du tableau) comme dit dans le dernier message devrait supprimer ce message d'avertissement.
Même si tu ne l'as pas vu, le même warning doit sortir pour RAM[1]. Dans ce cas, il faudrait mettre RAM+1 pour supprimer le message, c'est à dire l'adresse du tableau + 1(*sizeof(type du tableau)).
Voilà pour ce message d'avertissement.

Sinon, une remarque générale. Les quotes que tu sors là c'est 100% du C. Pourquoi le compiler en tant que C++ ???
Honnêtement, C et C++ sont deux langages différents, ayant des philosophies différentes et des buts différents.
Le C++ est construit autour de la POO. Ainsi, il existe des classes pour gérer les fichiers (ifstream, ofstream, fstream)  ou encore des objets permettant l'accès direct aux flux standards (cin, cout, ...) ainsi que des opérateurs de manipulation de ces flux. Bref, rien de ce que je vois ici en 3 lignes et que je verrais dans un code C++ ayant le même but.
Ce n'est pas une mauvaise critique (personnellement je préfère beaucoup le C au C++), mais ce code n'est pas du C++, donc compilons-le en C. Ou si du C++ est utilisé ailleurs, faisons tout le code en C++.

Ensuite, pour la question de départ, C++ vient directement du C et, à part quelques anciennes notations excentriques du C, tout ce qui existait en C a perduré en C++, donc les concepts de base comme le départ des tableaux sont identiques. Par contre j'ai en tête plusieurs exemples de codes en C compilant mal en C++ (même si ça n'a rien à voir ici), donc gardons chaque langage et chaque compilateur associé où il se doit ;-)

Voilà j'espère ne pas avoir été trop brouillon et confus dans la réponse comme mon état de fatigue et l'heure le permettraient...

S3cur3D

Edit: Désolé de me faire echo de toi, sirk390, j'étais parti faire autre chose au milieu de l'écriture de ma réponse..
« Dernière édition: 17 Août 2008 à 02:44:44 par S3cur3D » Journalisée

Being able to break security doesn't make you a hacker anymore than being able to hotwire cars makes you an automotive engineer.
_o_
Relecteur

Profil challenge

Classement : 42/54286

Membre Héroïque
*
Hors ligne Hors ligne
Messages: 1258


Voir le profil
« #5 le: 17 Août 2008 à 08:58:22 »

Je n'ai pas grand chose à ajouter à ce que vient de dire S3cur3d, sinon rappeler deux principes essentiels de la compilation, de mon point de vue :
1) Il faut configurer systématiquement son compilateur en lui demandant d'afficher tous les avertissements (pour gcc et dérivés, c'est le paramètre -Wall).
2) Un code correct ne doit afficher aucun avertissement à la compilation. Les avertissements préviennent de choses qui ne tiennent pas debout. Au mieux, il s'agit de bricolages sans conséquence, mais ce n'est pas propre. Au pire, un avertissement montre une erreur de programmation qui peut finir en crash. Je ne compte plus le nombre de fois où je me suis battu avec un bug idiot, avant de me rendre compte que le compilateur me prévenait depuis le début avec un avertissement d'un truc bizarre.
Journalisée

Les épreuves de hack de NC sont trop faciles ? Et pourtant ! Bienvenue dans la vraie vie : http://thedailywtf.com/Articles/So-You-Hacked-Our-Site!.aspx
mogg41

Profil challenge

Classement : 449/54286

Membre Senior
****
Hors ligne Hors ligne
Messages: 267

Mogg41 pour vous aider!


Voir le profil
« #6 le: 17 Août 2008 à 11:49:19 »

Merci à tous de vos réponses.

Je vais vous répondre dans l'ordre.

@Slack: J'avoue honteusement ne pas avoir été voir la déclaration de la fonction dans la librairie. Non pas par fainéantise mais juste parce que j'avais l'habitude d'utiliser la fonction fscanf de cette manière sans jamais avoir la moindre erreur d'exécution (en C). J'ai donc pensé, à tord, que cela venait d'une particularité du C++ plutôt que d'une erreur de codage de ma part

@simpsonsmaniac: Effectivement.

@sirk390: Tout me semble plus clair maintenant.

@S3cur3D: Je viens de me mettre au C++ il y a 2-3 jours. J'utilise dans mon programme des fonctions spécifiques au C++ mais je dois avouer qu'elles ne sont pas pour l'instant prédominantes.
J'ai décidé de coder mixte (C et C++). Puis au fur et à mesure d'éliminer les bouts de code en C par leur équivalent C++ afin de finir par coder qu'en C++. Peut être n'est-ce pas la bonne méthode pour passer du C au C++.

@_o_ :1) Je m'en vais ce ce pas configurer correctement mon compilateur.
2) Je sens que les avertissements vont pleuvoir dans tous mes anciens codes.

EDIT: Epreuve validée 1h après avoir lu vos réponses. Merci encore!
« Dernière édition: 17 Août 2008 à 12:47:00 par mogg41 » Journalisée

"Il ne savait pas que c'était impossible alors il l'a fait." Mark Twain
Pages: [1]
  Imprimer  
 
Aller à: