[C Unix] Ecrire dans un fichier...

Ecrire dans un fichier... [C Unix] - C - Programmation

Marsh Posté le 15-01-2008 à 17:22:02    

Bonjour,  
 
Je travaille actuellement pour l'école sur un dossier de C sous Unix.
C'est un long et fastidiueux projet traitant en grosse partie des IPC (files de messages, mémoires partagées and co).
 
Dans ce programme, je dois faire une simple écriture dans un fichier toute banale, je m''applique donc et je code ça (en simplifié) :  
 

Code :
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <fcntl.h>
  4. #include <sys/stat.h>
  5. #include <sys/types.h>
  6. #include <stdlib.h>
  7. int main (int argc, char *argv[])
  8. {
  9. int mavariable;
  10. if ((mavariable = open("Essai.test",O_RDWR|O_CREAT|O_EXCL|0777)) == -1)
  11. {
  12.  perror("Ouverture" );
  13.  exit(EXIT_FAILURE);
  14. }
  15. if(write(mavariable,"TEST",9) != 9)
  16. {
  17.  perror("Ecriture" );
  18.  exit(EXIT_FAILURE);
  19. }
  20. exit(EXIT_SUCCESS);
  21. return 0;
  22. }


 
Rien de ttrès compliqué mais voilà :  
 
gcc (ou cc) MonProgramme.c --> OK
./a.out --> Ecriture: Bad file descriptor
 
 :sweat:  
 
Ca doit être une connerie que j'ai loupé mais ca me rend dingue de chercher des heures pour un simple accès fichier alors que j'ai des tonnes de code à faire après ça... Vous ne voyez pas ce que j'ai loupé?  
 
Merci d'avance pour votre aide!

Reply

Marsh Posté le 15-01-2008 à 17:22:02   

Reply

Marsh Posté le 15-01-2008 à 17:45:28    

open() est une vieille instruction.
fopen() est utilisé plus volontiers.

int main (int argc, char *argv[])
{
   FILE *fp;
 
   if ((fp = fopen("Essai.test", "w" )) == -1) {
    perror("Ouverture" );
    exit(EXIT_FAILURE);
   }
 
   if (fwrite("TEST", 4, 1, fp) != 1) {
    perror("Ecriture" );
    fclose(fp);
    exit(EXIT_FAILURE);
   }
 
   fclose(fp);
   exit(EXIT_SUCCESS);
}

Reply

Marsh Posté le 15-01-2008 à 17:48:11    

C'est effectivement une connerie, le coup du message d'erreur faux...
if(write(mavariable,"TEST",9) != 9)
Tu écris 5 octets (en comptant le 0 final de chaine) et non 9. Ton test va donc être faux, et voir perror("Ecriture" ) appellé avec un errno quelconque.
if(write(mavariable,"TEST",9) != 5) serait déja un bon début pour ton test, non?
A+,


Message édité par gilou le 15-01-2008 à 17:58:20

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 15-01-2008 à 17:56:28    

olivthill a écrit :

open() est une vieille instruction.
fopen() est utilisé plus volontiers.

Euh... open, write... sont des instructions de plus bas niveau que fopen et fwrite.... Et je ne vois pas pourquoi on ne les utiliserais pas si on est dans un contexte ou les IO ne doivent pas être bufferisées.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 15-01-2008 à 17:58:57    

Exact pour open et write...  
 
J'ai changé 9 en 5 (je ne sais pas pourquoi j'avais mis 9 :)), ca ne change rien à mon erreur...

Reply

Marsh Posté le 15-01-2008 à 18:01:25    

Et write te repond qu'il a écrit combien d'octets?  
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 15-01-2008 à 18:16:36    

Il n'écrit rien : Ecriture: Bad file descriptor

Reply

Marsh Posté le 15-01-2008 à 18:21:56    

Je veux dire par la: quelle est la valeur retournée par l'appel à write -1? 0 ou 5?
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 15-01-2008 à 18:28:40    

1. write n'est pas une instruction mais un appel système : ce qu'il y a de plus bas niveau entre le noyau et le programme. fwrite est une fonction de bibliothèque qui travaille sur des flux bufferisés et qui utilise en interne write().
 
2. open, lorsqu'on l'utilise pour créer des fichiers prends 3 arguments et pas 2 : sépare tes flags de tes permissions.


Message édité par tpierron le 15-01-2008 à 18:29:09
Reply

Marsh Posté le 15-01-2008 à 18:40:44    

Ah oui, je n'avais pas fait gaffe a son open. Il n'a pas d'erreur, donc l'ouverture/creation doit être effectuée, mais ca a du mettre le souk dans les flags.
 
Note: Il y a effectivement un open sous Linux qui ne prend que deux arguments (sans doute implémenté a partir du 3e en prenant les permissions courantes utilisateur)
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);  
 
A+,


Message édité par gilou le 15-01-2008 à 18:41:15

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 15-01-2008 à 18:40:44   

Reply

Marsh Posté le 21-01-2008 à 12:03:37    

Jericho a écrit :

Bonjour,  
 
Je travaille actuellement pour l'école sur un dossier de C sous Unix.
C'est un long et fastidiueux projet traitant en grosse partie des IPC (files de messages, mémoires partagées and co).
 
Dans ce programme, je dois faire une simple écriture dans un fichier toute banale, je m''applique donc et je code ça (en simplifié) :  
 

Code :
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <fcntl.h>
  4. #include <sys/stat.h>
  5. #include <sys/types.h>
  6. #include <stdlib.h>
  7. int main (int argc, char *argv[])
  8. {
  9. int mavariable;
  10. if ((mavariable = open("Essai.test",O_RDWR|O_CREAT|O_EXCL|0777)) == -1)
  11. {
  12.  perror("Ouverture" );
  13.  exit(EXIT_FAILURE);
  14. }
  15. if(write(mavariable,"TEST",9) != 9)
  16. {
  17.  perror("Ecriture" );
  18.  exit(EXIT_FAILURE);
  19. }
  20. exit(EXIT_SUCCESS);
  21. return 0;
  22. }


 
Rien de ttrès compliqué mais voilà :  
 
gcc (ou cc) MonProgramme.c --> OK
./a.out --> Ecriture: Bad file descriptor
 
 :sweat:  
 
Ca doit être une connerie que j'ai loupé mais ca me rend dingue de chercher des heures pour un simple accès fichier alors que j'ai des tonnes de code à faire après ça... Vous ne voyez pas ce que j'ai loupé?  
 
Merci d'avance pour votre aide!


 
- tu as mis les permissions du fichier dans les options au lieu de les mettre après, ce qui te crée un fichier dans lequel tu ne peux pas écrire
- la taille de l'écriture n'est ni 9 ni 5 mais 4 ("TEST", on n'écrit pas le \0 dans un fichier). Ce n'est pas la cause de l'erreur mais c'est un bug quand meme.
- l'option O_EXCL est-elle justifiée ? elle fait échouer l'open si le fichier existe déjà.
- les permissions 0777 sont-elles justifiées ?
 
Proposition de code :

Code :
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <fcntl.h>
  4. #include <sys/stat.h>
  5. #include <sys/types.h>
  6. #include <stdlib.h>
  7. int
  8. main (int argc, char *argv[])
  9. {
  10.   int mavariable;
  11.   if ((mavariable =
  12.        open ("Essai.test", O_RDWR | O_CREAT, 0644)) == -1)
  13.     {
  14.       perror ("Ouverture" );
  15.       exit (EXIT_FAILURE);
  16.     }
  17.   if (write (mavariable, "TEST", 4) != 4)
  18.     {
  19.       perror ("Ecriture" );
  20.       exit (EXIT_FAILURE);
  21.     }
  22.   exit (EXIT_SUCCESS);
  23.   return 0;
  24. }

Reply

Marsh Posté le 21-01-2008 à 12:10:03    

Juste un autre petit détail : il n'est pas correct d'écrire

Code :
  1. if(write(mavariable,"TEST",9) != 9)
  2. {
  3. perror("Ecriture" );
  4. exit(EXIT_FAILURE);
  5. }


 
Le seul retour de la fonction write devant être traité comme une erreur est -1, dans tous les autres cas il faut refaire un write en décalant le buffer du nombre d'octets déjà écrits et en diminuant le nombre à écrire jusqu'à arriver à la fin. C'est aussi vrai pour read, fread, fwrite.
Ces fonctions doivent toujours être appelées dans une boucle.


Message édité par bobleblob le 21-01-2008 à 12:10:38
Reply

Sujets relatifs:

Leave a Replay

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