Code C-Lecture de fichiers à partir d'un dossier. - C - Programmation
Marsh Posté le 24-04-2011 à 21:19:10
Citation : fa=fopen("fp","rt" ); |
C'est faux ça! la tu essayes d'ouvrir un fichier nommé fp.
Il faudrait lire la page man de fopen (qui n'a jamais pris de t comme paramètre de mode de lecture que je sache) avant de coder.
fa=fopen(fp->d_name,"r" );
Code :
|
En faisant ceci, tu sautes la première entrée retournée par readdir.
Il va donc falloir faire
Code :
|
Et il faudra sans doute exclure le cas des entrées "." et ".." si readdir les renvoie (il me semble que c'est le cas)
A+,
Marsh Posté le 24-04-2011 à 22:23:16
Citation : Citation : |
J'avais essayé car je trouvais ça louche mais ça me mettait une erreur de compil, du coup j'était revenu en arrière. Mais cette fois j'ai copié ta ligne et pas d'erreur, j'avais du mal taper mon code^^.
Citation : |
Oui c'est sûr, je sait pas pourquoi j'ai mis cette ligne. Après pour les entrées . et .. je vois bien de quoi il est question, je vais arranger mon programme demain et voir si il y a encore des erreurs
Merci gilou
Marsh Posté le 24-04-2011 à 22:26:17
J'aurais à coder cela, je procéderais ainsi:
Code :
|
Bon, j'ai pas pu tester, car opendir, readdir et closedir n'ont pas d'équivalent sous windows pour mon compilo (Digital Mars).
A+,
Marsh Posté le 25-04-2011 à 16:28:08
Bonjour!!
Alors pour mon code, j'ai tout arrangé comme il faut et j'ai toujours le même résultat: le nom des fichiers mais pas leur contenu. Cependant, je pense vraiment que c'est un problème d'affichage et pas de code car j'ai copié tout ton message et même résultat (il ne tiens pas compte du fgets). Je devrais déja commencer l'exploitation des données voir si il y a réellement un problème. Sinon pour le strcmp(), j'ai fait des recherches et je trouve ça bien utile pour le programme, merci !
Edit: je commence l'exploitation maintenant, je reviendrai pour dire si sa bloque encore ou si j'y suis enfin arrivé^^
Marsh Posté le 25-04-2011 à 17:34:05
Un problème que je vois avec ce code, est que le champ d_name ne contient pas le nom du répertoire qui a été passé en arguement à opendir, donc le fopen() va retourner systématiquement NULL.
Bref, une petite modif du genre, ça devrait aller mieux:
Code :
|
Marsh Posté le 25-04-2011 à 17:52:28
tpierron a écrit : Un problème que je vois avec ce code, est que le champ d_name ne contient pas le nom du répertoire qui a été passé en arguement à opendir, donc le fopen() va retourner systématiquement NULL. |
Bien vu!
Comme j'ai pas pu compiler et faire tourner le code pour le tester, ça m'a échappé.
Pour être un poil plus efficace, sous unix ou linux, j'aurais juste fait un chdir("Temperature Data Files" ) puis un opendir("." ), ce qui évite les multiples appels à snprintf.
A+,
Marsh Posté le 25-04-2011 à 19:15:36
Salut tpierron,
En effet, avec snprintf, que j'ai adapté sur mon programme, on a bel et bien le résultat attendu.
Par contre, je commence la programmation et j'ai seulement pu adapter ton code sans vraiment tout comprendre (enfin j'ai compris un minimum pour l'adapter quand même^^) :
Code :
|
Je suis allé voir sur internet mais les rares pages d'explications en français ne m'ont pas aidé. J'ai cru comprendre que snprintf assigne à une chaine de caractères (1er argument) ce qui ce trouve dans le 3ème argument, pour un maximum de x caractères déterminés par le 2eme argument (ici, 256). Mais du coup, je ne vois pas la différence avec le code précédent. Ou alors, on ne peut simplement pas mettre de d_name comme argument pour un fopen?
Sinon, pourquoi ne peut-on pas mettre
Code :
|
?
Car tous les fichiers du dossier ont des noms uniques sur mon ordinateur
Désolé pour les questions en parallèle mais sa me laisse perplexe^^
Encore merci à vous !
Marsh Posté le 25-04-2011 à 20:58:14
>> Sinon, pourquoi ne peut-on pas mettre snprintf(fn,sizeof fn,"%s",fp->d_name);
Parce que le nom fp->d_name est relatif au répertoire ouvert avec opendir, mais que fopen prend un nom relatif au répertoire d'ou le programme s'est lancé.
D'ou deux solutions:
Soit déduire le nom relatif au répertoire d'ou le programme s'est lancé à partir du nom relatif au répertoire ouvert avec opendir et du nom du répertoire ouvert avec opendir, c'est ce qui est fait avec snprintf
Soit changer de répertoire de travail pour fopen et mettre comme répertoire de travail celui ou les fichiers se trouvent. C'est ce qui peut être fait avec chdir.
A+,
Marsh Posté le 25-04-2011 à 21:17:43
Merci pour la clarification, j'ai tout compris. Eh bien, je crois que c'est ok pour l'exploitation des données, merci encore à tous les deux!!
Marsh Posté le 25-04-2011 à 22:07:28
Si tu es souus unix/linux (ce qui devrait être la cas si j'ai bien compris, tu peux procéder comme suit:
Code :
|
A+,
Marsh Posté le 26-04-2011 à 15:54:05
Non non, je ne suis pas sous linux. Mais merci quand même!!
Marsh Posté le 26-04-2011 à 16:20:18
Mais si tu n'est pas sous linux, le code qu'on t'a donné ne vas pas marcher, vu que opendir, closedir et readdir sont pas à priori supportées dans l'environnement windows.
Bon si tu fais ça avec gcc sous cygwin, je dis pas, mais sinon...
A+,
Marsh Posté le 26-04-2011 à 16:31:10
gilou a écrit : Mais si tu n'est pas sous linux, le code qu'on t'a donné ne vas pas marcher, vu que opendir, closedir et readdir sont pas à priori supportées dans l'environnement windows. |
Ça fonctionne aussi avec MinGW (inclus avec Code::Blocks par ex.). Ça ne fonctionnera sans doute pas avec Visual Studio, ces fonctions ne font pas partie de la msvcrt. Là va falloir utiliser l'API Win32.
Marsh Posté le 26-04-2011 à 17:13:10
Oui je suis bien sur MinGW, donc pas de problème de ce côté la
Marsh Posté le 26-04-2011 à 19:51:31
Sinon il faut appeler l'API Windows. Ceci passe avec mon compilo digital mars.
Code :
|
Bon, j'ai pas testé a fond, il reste à voir s'il y a des problèmes d'encoding entre ce qui est retourne par FindFileData.cFileName et ce qui est attendu par fopen ou s'il y a des problèmes nom court/nom long.
A+,
Marsh Posté le 26-04-2011 à 22:27:48
Aïe, j'ai du mal à comprendre le code, trop différent de ce que j'ai l'habitude de faire. Ca doit être dù au compilo, je ne connais que mingw^^.
Sinon, je voulais vous demander à propose de cette partie du code :
Code :
|
En fait ça veut dire que si la chaine correspondant à fp->d_name est "." ou "..", on arrête pas la boucle c'est ça? En fait je pensais que justement, on avais toujours des fichiers nommés "." et ".." quand on lis les fichiers d'un dossier et qu'il fallait les retirer, mais en fait il font qu'on ait ces points car ils indiquent que les fichiers appartiennent à un dossier?? Je suis un peu perdu ...
Bonne soirée
Marsh Posté le 26-04-2011 à 22:44:41
"continue" signifie que tu retourne a l'evaluation de la condition de la boucle :
entry = readdir(dp)
Dans ce cas precis, cela signifie que tu ne veux pas traiter ces fichiers.
Marsh Posté le 27-04-2011 à 00:00:06
Ah d'accord, j'avais donc bien compris qu'il ne fallait pas traîter les fichiers nommés "." et ".." mais j'avais mal compris la fonction de continue; c'est la petite flèche bleue qu'affiche le CSD qui m'a trompé^^merci!
Marsh Posté le 24-04-2011 à 20:11:20
Bonjour,
Avant toute chose, je ne peut travailler qu'en code C (donc pas en C++) et mes connaissances vont des bases (tableaux, boucles, fonctions, pointeurs, etc) que j'ai vues en cours (je n'en aurai plus) jusqu'à la manipulation de fichiers (lire, éditer, ouvrir) que j'ai apprise sur internet (site du zéro), enfin bon c'est peut-être de la base pour vous aussi^^. Au niveau de la manipulation de dossiers, je bloque un peu, c'est d'ailleurs pourquoi je viens vous demander de l'aide:
Dans le cadre d'un projet informatique, je dois télécharger un dossier sur un site internet; dossier dans lequel se trouvent des centaines de fichiers avec des données chiffrées dans chaque fichier(je vous donne un modèle):
01 01 2001 25
01 02 2001 24.6
...
...
...
25 06 2006 26
c'est donc une suite de chiffres présentés sous forme de tableau (ça représente le jour, le mois, l'année et la température...avec un fichier pour chaque ville,donc une centaine de fichiers).
Je vous dit ce que j'ai fait dès le début au cas où j'aurai fait une erreur avant de commencer à programmer:
J'ai donc tout d'abord téléchargé le dossier dans C:\ en zip puis j'ai extrait le dossier, que j'ai copié dans mon répertoire Code C, où je mets mes autres programmes jGrasp.
Il faut donc maintenant que je lise les fichiers du dossier. Les fichiers étant nombreux et ayant des noms complexes, les ouvrir un par un avec fopen pour chaque serait une solution trop longue.
Il faut donc que j'ouvre le dossier. L'idéal je pense (car je dois exploiter les données), c'est d'ouvrir le dossier, puis le 1er fichier, mettre les données dans un tabeau, l'exploiter, écraser ce fichier par le 2ème fichier et refaire la même démarche(écraser le tableau précédant), et ce jusqu'au dernier fichier, tout en stockant les résultats de l'exploitation des données.
J'ai donc essayé d'ouvrir le dossier et de faire une boucle qui permet de faire tourner les fichiers. Pour vérifier le bon déroulement du programme, j'ai fait un printf des 20 premiers caractères du fichier ainsi que son nom.
J'ai donc le code suivant :
J'obtiens bien les noms des fichiers qui se trouvent dans le dossier (enfin juste les derniers mais je crois que c'est par manque de place dans la fenêtre) mais je n'ai pas les 20 premiers caractères.
Avant de manipuler les dossiers, j'ai fait la même chose sur le 1er fichier du dossier :
Ici, j'ai bien le contenu du fichier.
Le fichier exploité n'est pas dans le dossier (j'en ai fait une copie un niveau plus haut, où j'ai tous mes programmes jGrasp ainsi que le fameux dossier) car si je prends directement le fichier dans le dossier, ça ne marche pas (c'est peut-être une des raisons de mon problème)
Sinon, autre petite question: sur l'énoncé il est écrit que je dois utiliser, entre autres, fread et feof...d'après ce que j'ai lu sur internet, on peut tout faire avec fgets (donc sans fread, mais peut être plus facile avec fread?) et pour feof, détecter la fin du fichier n'est pas indispensable grace à la boucle
Je me trompe?
Merci d'avance pour votre aide que j'apprécie et sachez, même si ça n'a pas d'importance que vous n'aidez pas seulement une personne qui doit rendre un devoir, mais une personne qui s'intéresse à la programmation (et qui en fait tous les week-ends malgré le fait que mes études n'ont pas trop de lien avec l'informatique)
Bonne journée à tous !