fopen ne reconnait pas un fichier existant

fopen ne reconnait pas un fichier existant - C - Programmation

Marsh Posté le 14-04-2005 à 18:16:02    

Bonjour, j'ai un petit souci sur un fichier " toto " que je cherche à ouvrir en lecture. Si j'écris :
 

Code :
  1. fopen(toto,"r" );


 
cette fonction retourne un NULL, indiquant que le fichier n'existe pas. Avec :
 

Code :
  1. fopen(./toto,"r" );


 
Le fichier est reconnu et ouvert normalement.
 
Mon problème vient du fait que je souhaiterais conserver la première syntaxe, notamment pour des problèmes de portabilités sous Windows (ou cette syntaxe initiale fonctionne). Sauriez vous comment forcer mon programme C a reconnaître l'existence d'un fichier défini localement, sans être contraint d'ajouter "./" avant son nom ?

Reply

Marsh Posté le 14-04-2005 à 18:16:02   

Reply

Marsh Posté le 14-04-2005 à 18:25:35    

nathan_g a écrit :

Bonjour, j'ai un petit souci sur un fichier " toto " que je cherche à ouvrir en lecture. Si j'écris :
 

Code :
  1. fopen(toto,"r" );


 
cette fonction retourne un NULL, indiquant que le fichier n'existe pas. Avec :
 

Code :
  1. fopen(./toto,"r" );


 
Le fichier est reconnu et ouvert normalement.
 
Mon problème vient du fait que je souhaiterais conserver la première syntaxe, notamment pour des problèmes de portabilités sous Windows (ou cette syntaxe initiale fonctionne). Sauriez vous comment forcer mon programme C a reconnaître l'existence d'un fichier défini localement, sans être contraint d'ajouter "./" avant son nom ?


 
Hum... t'as essayé

Code :
  1. fopen("toto","r" );

???

Reply

Marsh Posté le 14-04-2005 à 18:32:06    

En fait, je n'ai pas toto directement dans fopen mais une chaine de caractères " myfile " contenant le nom du fichier (j'ai été un peu rapide à l'écrire). Initialement, j'avais :
 

Code :
  1. myfile = "toto";
  2. fopen(myfile,"r" );


 
qui ne marchait pas ! Mais :
 

Code :
  1. myfile = "./toto";
  2. fopen(myfile,"r" );


 
marche !
 
 
Je voudrais savoir comment forcer la première syntaxe (qui marche sous Windows mais pas sous Linux) à marcher (sans avoir besoin de recourir au ./ supplémentaire.
 
En gros comment faire reconnaître simplement à fopen l'existence de fichiers locaux ?

Reply

Marsh Posté le 14-04-2005 à 19:24:29    

t'as du faire une erreur ailleurs, c'est toujours le chemin courant qui est utilisé.

Reply

Marsh Posté le 14-04-2005 à 19:57:12    

nathan_g a écrit :

En fait, je n'ai pas toto directement dans fopen mais une chaine de caractères " myfile " contenant le nom du fichier (j'ai été un peu rapide à l'écrire). Initialement, j'avais :
 

Code :
  1. myfile = "toto";
  2. fopen(myfile,"r" );


 
qui ne marchait pas ! Mais :
 

Code :
  1. myfile = "./toto";
  2. fopen(myfile,"r" );


 
marche !


 
Commence par essayer

fopen("toto", "r" )

pour écarter tout doute de la fonction "fopen" (que je pense quand-même hors de cause)
 
Ensuite, parle-nous un peu plus de cette variable "myfile", son type, comment tu la remplis, etc...


Message édité par Sve@r le 14-04-2005 à 19:59:13
Reply

Marsh Posté le 15-04-2005 à 04:12:24    

nathan_g a écrit :

Bonjour, j'ai un petit souci sur un fichier " toto " que je cherche à ouvrir en lecture. Si j'écris :
 

Code :
  1. fopen(toto,"r" );


 
cette fonction retourne un NULL, indiquant que le fichier n'existe pas. Avec :
 

Code :
  1. fopen(./toto,"r" );


 
Le fichier est reconnu et ouvert normalement.
 
Mon problème vient du fait que je souhaiterais conserver la première syntaxe, notamment pour des problèmes de portabilités sous Windows (ou cette syntaxe initiale fonctionne). Sauriez vous comment forcer mon programme C a reconnaître l'existence d'un fichier défini localement, sans être contraint d'ajouter "./" avant son nom ?


 
 :D quand je suis passé à linux j'ai eu ce problème, essaye un strcat("",chaine) ou chaine est la chaine de caractère qui contient le nom du fichier, juste avant le fopen, depuis que je fais ça, j'ai plus de problème de portabilité! (en tout cas à ce niveau là...)
bonne chance  :hello:

Reply

Marsh Posté le 15-04-2005 à 08:20:04    

Apocalypse13 a écrit :

:D quand je suis passé à linux j'ai eu ce problème, essaye un strcat("",chaine) ou chaine est la chaine de caractère qui contient le nom du fichier, juste avant le fopen, depuis que je fais ça, j'ai plus de problème de portabilité! (en tout cas à ce niveau là...)


C'est de la magie ?
 
strcat("",chaine) invoque un comportement indéfini.  

  • "" est une chaine non modifiable
  • même si "" était modifiable, elle n'est pas assez grande pour autre chose que "", c'est à dire un tableau de 1 char valant 0 (fin de chaine).


Ce n'est donc pas la solution.
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 15-04-2005 à 08:53:32    

Merci de toutes ces réponses !
 
En fait, je me suis depuis rendu compte que le problème était légèrement différent. Au début, je croyait que myfile était égale à "toto" et ça ne marchait pas ! En imposant :
 

Code :
  1. myfile = "./toto";
  2. fopen(myfile,"r" );


 
Mon fichier toto peut enfin être lu. Ainsi,je croyais alors que le problème se situait dans cette présence ou non du "./" devant le nom du fichier. Je me suis rendu compte, en analysant caractère par caractère l'ensemble de la chaine de caractères " myfile " que, apparemment, il s'agisssait plutot d'un problème sur le caractère suivant la fin du nom du fichier (celui-ci est contenu seulement au début de " myfile " qui admet une taille bcp plus importante).
 
En gros, si je mets  
 

Code :
  1. myfile = "toto";
  2. fopen(myfile,"r" );


 
Ca fonctionne car :
 

Code :
  1. printf("myfile[4] = %i ",myfile[4]);
  2. /* sort 0 à l'écran (1er caractère ASCII) */
  3. /* myfile est rempli avec des caractères ASCII de code déc. 0 ensuite */


 
A l'inverse, si je me contente d'une syntaxe (écrite sous Windows et qui fonctionne sous ce système) où " myfile " est initialisé - je ne sais pas trop comment - bien avant, on a :
 

Code :
  1. printf("myfile %s ",myfile);
  2. /* sort toto à l'écran */
  3. fopen(myfile,"r" );


 
Ca ne fonctionne pas car :
 

Code :
  1. printf("myfile[4] %i",myfile);
  2. /* sort 3 à l'écran (1er caractère ASCII) */
  3. /* en tout cas, un caractère différent de 0 */


 
En gros il me semble que le caractère suivant la fin du nom du fichier dans " myfile " est déterminant pour permettre son ouverture. Sous linux, il apparait codé en ASCII en 3 (peut-être cela pourrait être n'importe quoi d'autre ?) et ça ne marche pas. Il faut imposer myfile = "toto" pour que cela fonctionne car le caractère suivant est alors un "0" en ASCII.
 
J'espère avoir été à peu près clair (même si j'ai été long ! ). Est ce que quelqu'un saurait comment résoudre mon problème ?
 
Ce qui m'énerve surtout est que je rencontre fréquemment sur ce type de difficultés sur mon code que je cherche à passer sous Linux alors qu'il a été développé sous Windows.
Je vais voir également si le conseil de Apocalypse13 est valable mais d'autre explications/conseils seraient les bienvenus.
 
Merci encore de l'aide que vous m'avez déja fournie.
 

Reply

Marsh Posté le 15-04-2005 à 08:55:25    

Bien évidemment, c'était plutot :
 

Code :
  1. printf("myfile[4] %i",myfile);
  2. /* sort 3 à l'écran (4ème caractère ASCII) */
  3. /* en tout cas, un caractère différent de 0 */


Reply

Marsh Posté le 15-04-2005 à 09:15:51    

nathan_g a écrit :


A l'inverse, si je me contente d'une syntaxe (écrite sous Windows et qui fonctionne sous ce système) où " myfile " est initialisé - je ne sais pas trop comment


Justement, ça m'interesse de savoir comment. Si ta chaine est mal formée, il faut en connaître la raison. C'est probablement une erreur de codage ou une mauvaise utilisation des fonctions systèmes...
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 15-04-2005 à 09:15:51   

Reply

Marsh Posté le 15-04-2005 à 12:40:24    

Emmanuel Delahaye a écrit :

C'est de la magie ?
 
strcat("",chaine) invoque un comportement indéfini.  

  • "" est une chaine non modifiable
  • même si "" était modifiable, elle n'est pas assez grande pour autre chose que "", c'est à dire un tableau de 1 char valant 0 (fin de chaine).


Ce n'est donc pas la solution.


 
Et pourtant, depuis que j'utilise les trois systèmes linux, mac et windows : je n'ai pas trouvé d'autres solutions, et ça marche.... promis même si je ne peux expliquer pourquoi  :pt1cable:

Reply

Marsh Posté le 15-04-2005 à 12:53:23    

si ca marche avec ton strcat, ca veux dire que ca marche sans car en plus d'etre foireux il ne modifie pas chaine

Reply

Marsh Posté le 15-04-2005 à 12:58:58    

Apocalypse13 a écrit :

Et pourtant, depuis que j'utilise les trois systèmes linux, mac et windows : je n'ai pas trouvé d'autres solutions, et ça marche.... promis même si je ne peux expliquer pourquoi  :pt1cable:


ouais ouais si ça marche c'est que c'est correct alors.

Reply

Marsh Posté le 15-04-2005 à 13:57:54    

Moi ce que je trouve bizarre c'est ça :

nathan_g a écrit :


myfile = "./toto";


 
Surtout quand je lit ça juste après :

nathan_g a écrit :


" myfile " qui admet une taille bcp plus importante


 
Personnellement pour remplir une chaîne, je fais plutôt un truc du style :
strcpy(myfile, "toto" );
 
(en étant sûr que myfile est assez grand pour le contenir, autrement strncpy)

Reply

Marsh Posté le 15-04-2005 à 17:49:04    

Tarabiscote a écrit :

Moi ce que je trouve bizarre c'est ça :
 
 
Surtout quand je lit ça juste après :
 
 
Personnellement pour remplir une chaîne, je fais plutôt un truc du style :
strcpy(myfile, "toto" );
 
(en étant sûr que myfile est assez grand pour le contenir, autrement strncpy)


 
T'as le droit d'écrire

Code :
  1. char *myfile="toto"

mais tu dois savoir ce que tu fais
=> la chaîne "toto" est qqpart en mémoire et tu déclares un pointeur pointant vers ce "qqpart"
 
Ta soluce est plus conforme avec le but généralement à atteindre => copier du texte dans une variable suffisemment grande pour le contenir => strcpy() ou strncpy()
 
Maintenant, pour connaître vraiment le contenu de "myfile", au lieu de faire du

Code :
  1. printf("myfile=%s\n", myfile)

, je ferais plutôt ça:

Code :
  1. printf("myfile=<%s>\n", myfile); // Histoire d'être certain qu'il n'y a rien avant ni après
  2. for (i=0; i < strlen(myfile); i++)  // Vivi c'est pas optimisé mais c'est juste pour vérifier
  3.     printf("carac %d=%d\n", i, myfile[i]);


 


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 15-04-2005 à 18:05:05    

Je disais ça uniquement parce que d'après ce qu'il disait, il devait avoir allouer de la mémoire pour sa chaîne.
Et donc j'expliquais d'où pouvait venir l'erreur dans ce cas.
 
En fait tant qu’on n’aura pas vu le reste du code, il sera difficile de dire où est vraiment l'erreur.


Message édité par Tarabiscote le 15-04-2005 à 18:38:32
Reply

Marsh Posté le 18-04-2005 à 08:47:53    

Je suis épaté par le succès de cette question ;)
 
En fait, j'étais en train de reprendre un programme écrit par une autre personne et de le compiler sous Linux. Je ne comprenais pas pourquoi ce fichier qui existait pourtant n'était pas reconnu par fopen.
 
Sans entrer dans le détail (en fait le code mélangeait fortran et C), l'erreur était dans la construction du nom du fichier et le fait qu'il était passé en argument directement dans une fonction avec qqch du genre :
 

Code :
  1. bool commencer_lect(char*);
  2. ...
  3. flag = commencer_lect(toto);


 
 
(en fait ce type de syntaxe l'était en fortran).
 
En gros on passait une chaine de caractères sans savoir vraiment les caractèrtes suivant le dernbie o ce qui ne permettait pas de le retrouver (le problème était plus complexe mais la je simplifie) ;).
 
Encore merci à ce qui m'ont fourni des explications sur ce problème !

Reply

Marsh Posté le 18-04-2005 à 15:04:01    

Et oui, en fortran les chaînes c'est une suite de caractères + une longueur, pas une une suite de caractères + '\0' final comme en C.

Reply

Marsh Posté le 18-04-2005 à 15:25:07    

Mouais ...
 
En fait, le problème était plutot que, en fortran sous Windows, une chaine de caractère passée aussi salement (cad directement) était acceptée par le reste du programme (en l'occurence elle se poursuivait pas des espaces après le dernier caractère (le " o " ) ). Sous Linux, ce n'était plus le cas, les caractères suivant étaient différents (je crois qu'il s'agissait d'un \r après le " o " puis d'espace).
Ma correction  a résolu ce problème.

Reply

Marsh Posté le 18-04-2005 à 18:06:05    

nathan_g a écrit :

Je suis épaté par le succès de cette question ;)


Ben ça nous intéressait parce qu'on savait fondamentalement qu'il n'y avait aucune raison que fopen() réussisse avec "./toto" et pas avec "toto"
 

nathan_g a écrit :

Ma correction  a résolu ce problème.

Maintenant "fopen" ne marche plus du tout :D  


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed