Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1677 connectés 

  FORUM HardWare.fr
  Programmation
  C

  [C Unix] Ecrire dans un fichier...

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C Unix] Ecrire dans un fichier...

n°1671618
Jericho
Posté le 15-01-2008 à 17:22:02  profilanswer
 

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!

mood
Publicité
Posté le 15-01-2008 à 17:22:02  profilanswer
 

n°1671641
olivthill
Posté le 15-01-2008 à 17:45:28  profilanswer
 

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);
}

n°1671647
gilou
Modérateur
Modzilla
Posté le 15-01-2008 à 17:48:11  profilanswer
 

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é!  --
n°1671664
gilou
Modérateur
Modzilla
Posté le 15-01-2008 à 17:56:28  profilanswer
 

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é!  --
n°1671670
Jericho
Posté le 15-01-2008 à 17:58:57  profilanswer
 

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...

n°1671673
gilou
Modérateur
Modzilla
Posté le 15-01-2008 à 18:01:25  profilanswer
 

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é!  --
n°1671685
Jericho
Posté le 15-01-2008 à 18:16:36  profilanswer
 

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

n°1671692
gilou
Modérateur
Modzilla
Posté le 15-01-2008 à 18:21:56  profilanswer
 

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é!  --
n°1671697
tpierron
Posté le 15-01-2008 à 18:28:40  profilanswer
 

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
n°1671714
gilou
Modérateur
Modzilla
Posté le 15-01-2008 à 18:40:44  profilanswer
 

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é!  --
mood
Publicité
Posté le 15-01-2008 à 18:40:44  profilanswer
 

n°1674309
bobleblob
Posté le 21-01-2008 à 12:03:37  profilanswer
 

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. }

n°1674312
bobleblob
Posté le 21-01-2008 à 12:10:03  profilanswer
 

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

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  [C Unix] Ecrire dans un fichier...

 

Sujets relatifs
[Access] Importation de fichier texte et perte des espacesGenerer un fichier ODB
modifier la date de création d'un fichier[PERL] de l'aide pour petite manip de champs dans un fichier
Inversser les slashes dans un chemin de fichierLire et écrire dans une base de données SQL via Excel
lancer plusieurs fichier sur imprimante réseauÉcrire une fonction indicatrice
Modifier un fichier texte en phpDébut du fichier au format RTF
Plus de sujets relatifs à : [C Unix] Ecrire dans un fichier...


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR