Ecrire sur une position donnée

Discutez d'informatique ici !
Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 18:42

Ecrire sur une position donnée

par Rockleader » 07 Jan 2014, 13:21

Je voudrais arriver à écrire dans un fichier sur une position donné.

J'ai vu les fonctions fread et fwrite; mais trop tard j'ai déjà commencé mon travail avec des fprintf et fscanf


Je me demandais donc si ceci pouvait marcher

Code: Tout sélectionner
void read_block(int pos,FILE* disk_id)
{
   if (disk_id != NULL)
      {
                        uchar block;
         fseek(disk_id,BLOCK_SIZE,pos); /*on se place à la position pos dans le fichier*/
         fscanf(disk_id,"%hhu",block); /*on stocke dans block la chaine de BLOCK_SIZE uchar ???? */
      }
}
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !



Avatar de l’utilisateur
ampholyte
Membre Transcendant
Messages: 3940
Enregistré le: 21 Juil 2012, 07:03

par ampholyte » 07 Jan 2014, 13:46

Bonjour,

Si les choses sont bien faites normalement cela ne devrait pas poser de problème.

Mais il faut que tu testes pour vérifier que cela fonctionne. Il te suffit de faire un fprintf sur block pour vérifier que cela concorde bien.

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 18:42

par Rockleader » 07 Jan 2014, 13:50

Nop; j'ai fait des tests et ça a planté ça n'affiche pas ce qu'il faut, je suis en train de voir pour essayer de passer tout avec write et read...

En revanche ça ne fonctionne pas comme ça devrait
char tab[]="coucou";
fwrite( tab , sizeof(tab[0]) , sizeof(tab)/sizeof(tab[0]) , disk_id);
fread( tab , sizeof(tab[0]) , sizeof(tab)/sizeof(tab[0]) , disk_id);


fwrite écrit bien dans mon fichier, mais fread ne m'affiche rien; erreur de ma part ?
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Avatar de l’utilisateur
ampholyte
Membre Transcendant
Messages: 3940
Enregistré le: 21 Juil 2012, 07:03

par ampholyte » 07 Jan 2014, 13:52

Lorsque tu fais un fscanf, il va jusqu'à la fin de la ligne, donc il faut être sûr que tu n'ais qu'un seul paramètre dans ta chaine.

Malgré tout je pense qu'une solution avec read / write est plus simple et plus préférable que l'utilisation d'un fscanf.

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 18:42

par Rockleader » 07 Jan 2014, 14:02

ampholyte a écrit:Lorsque tu fais un fscanf, il va jusqu'à la fin de la ligne, donc il faut être sûr que tu n'ais qu'un seul paramètre dans ta chaine.

Malgré tout je pense qu'une solution avec read / write est plus simple et plus préférable que l'utilisation d'un fscanf.


Désolé, j'ai édité le dernier post avant que tu n'écrives ;)

Deux soucis; que je fasse

fwrite( tab , sizeof(tab[0]) , sizeof(tab)/sizeof(tab[0]) , disk_id);

ou un fseek avant; j'écris dans les deux cas au début du fichiers (que j'ouvre en r+)

et le freed n'affiche rien.
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

joel76
Membre Relatif
Messages: 230
Enregistré le: 11 Fév 2013, 15:31

par joel76 » 07 Jan 2014, 14:08

Le fscanf ne peut-être utilisé que pour lire du texte.
Si on fait un fwrite, il faut absolument faire un fread sinon c'est de la mauvaise conception de programme.
De tout façon, après le fwrite il faut faire un fflush(disk_id) pour forcer l'écriture sur le disque (apparemment pas obligatoire, je viens de tester chez moi), et revenir à la position où on a écrit avec un fseek pour pouvoir lire correctement ce qui a été écrit.

Avatar de l’utilisateur
ampholyte
Membre Transcendant
Messages: 3940
Enregistré le: 21 Juil 2012, 07:03

par ampholyte » 07 Jan 2014, 14:09

Peux-tu mettre ton code contenant l'écriture et la lecture également avec ton fseek complet ? Après ton fwrite tu dois remettre le curseur de ton flux au début de ton fichier.

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 18:42

par Rockleader » 07 Jan 2014, 14:12

Bien; alors la séquence suivante; n'affiche rien du tout

Code: Tout sélectionner
void read_block(int pos,FILE* disk_id)
{
   if (disk_id != NULL)
      {
                        fseek(disk_id,BLOCK_SIZE,pos);
                        char tab[]="coucou";
         fwrite( tab , sizeof(tab[0]) , sizeof(tab)/sizeof(tab[0]) , disk_id);
         fseek(disk_id,BLOCK_SIZE,pos);
         fread( tab , sizeof(tab[0]) , sizeof(tab)/sizeof(tab[0]) , disk_id);
      }
}


Main

Code: Tout sélectionner
FILE *source; 
   source = fopen("test.txt", "r+" );
   read_block(5,source);
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

joel76
Membre Relatif
Messages: 230
Enregistré le: 11 Fév 2013, 15:31

par joel76 » 07 Jan 2014, 14:16

Ceci fonctionne chez moi :
Code: Tout sélectionner
int main()
{
   char tab[]="coucou";
   char tab1[1024];
   size_t nb;
   FILE *f = fopen("C:\\a-travail\\developpements\\Visual Studio\\C\\test_fseek\\test.txt", "wb+");
   fwrite( tab , sizeof(tab[0]) , sizeof(tab)/sizeof(tab[0]) , f);
   fseek(f, -sizeof(tab)/sizeof(tab[0]), SEEK_CUR) ;
   nb = fread( tab1 , sizeof(tab[0]) , sizeof(tab)/sizeof(tab[0]) , f);
   fclose(f);
   tab1[nb] = 0;
   puts(tab1) ;
   _getch();
 return 0;
}

Avatar de l’utilisateur
ampholyte
Membre Transcendant
Messages: 3940
Enregistré le: 21 Juil 2012, 07:03

par ampholyte » 07 Jan 2014, 14:21

En modifiant rapidement ton code, ceci fonctionne chez moi :

Code: Tout sélectionner
void read_block(int pos,FILE* disk_id)
{
    if (disk_id != NULL)
    {

        char tab[]="coucou";
   
        fseek(disk_id,pos,SEEK_SET);
        fwrite( tab , sizeof(tab[0]), strlen(tab), disk_id);
        fseek(disk_id, pos, SEEK_SET);
        fread( tab , sizeof(tab[0]) , sizeof(tab)/sizeof(tab[0]) , disk_id);
        fprintf(stderr, "%s\n", tab);
    }
}

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 18:42

par Rockleader » 07 Jan 2014, 14:23

ampholyte a écrit:En modifiant rapidement ton code, ceci fonctionne chez moi :

Code: Tout sélectionner
void read_block(int pos,FILE* disk_id)
{
    if (disk_id != NULL)
    {

        char tab[]="coucou";
   
        fseek(disk_id,pos,SEEK_SET);
        fwrite( tab , sizeof(tab[0]), sizeof(tab)/sizeof(tab[0]), disk_id);
        fseek(disk_id, pos, SEEK_SET);
        fread( tab , sizeof(tab[0]) , sizeof(tab)/sizeof(tab[0]) , disk_id);
        fprintf(stderr, "%s\n", tab);
    }
}


Oui mais là tu te sers de SEEK_SET et non de la position en paramètres !!!
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Avatar de l’utilisateur
ampholyte
Membre Transcendant
Messages: 3940
Enregistré le: 21 Juil 2012, 07:03

par ampholyte » 07 Jan 2014, 14:24

Et bien si ma position correspond à mon offset à partir du début.
Code: Tout sélectionner
 fseek(disk_id,pos,SEEK_SET);

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 18:42

par Rockleader » 07 Jan 2014, 14:29

Ce que je veux dire avec ça; tu vas avancer de pos octets à partir de la position courante SEEK_SET


Moi je veux avancer de BLOCK_SIZE octet à partir de la position pos ;)
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Avatar de l’utilisateur
ampholyte
Membre Transcendant
Messages: 3940
Enregistré le: 21 Juil 2012, 07:03

par ampholyte » 07 Jan 2014, 14:31

D'accord utilise alors la technique de joel76 c'est à dire de faire un fseek négatif après ton fwrite.

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 18:42

par Rockleader » 07 Jan 2014, 14:40

Toujours pas

Du mieux je prend bien le décalage et j'écris au bon endroit au début, en revanche je n'ai toujours pas l'affichage de read

Code: Tout sélectionner
void read_block(int pos,FILE* disk_id)
{
   if (disk_id != NULL)
      {
         fseek(disk_id,BLOCK_SIZE,pos);
         char tab[]="coucou";
         fwrite( tab , sizeof(tab[0]) , sizeof(tab)/sizeof(tab[0]) , disk_id); // ==> OK
         fseek(disk_id,-BLOCK_SIZE,SEEK_CUR);
         fread( tab , sizeof(tab[0]) , sizeof(tab)/sizeof(tab[0]) , disk_id); // aucun affichage
      }
}


Y a t'il un moyen de faire une sorte de code de retour sur fread pour voir si la lecture se fait ?

EDIT; pur l'écriture j'ai parlé trop vite, ça marche pour pos=1 et pos=2 ça me mettre respectivemment 4 et 8 espace; mais pour pos=3 ça me récrit au début du fichier.
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

joel76
Membre Relatif
Messages: 230
Enregistré le: 11 Fév 2013, 15:31

par joel76 » 07 Jan 2014, 14:43

Euh, tu fais bien un puts de tab, non ?
Teste les retour de fseek, si c'est -1 il y a un problème.

Avatar de l’utilisateur
ampholyte
Membre Transcendant
Messages: 3940
Enregistré le: 21 Juil 2012, 07:03

par ampholyte » 07 Jan 2014, 14:46

Est-ce que tu fais bien un printf de tab après ton fread ?

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 18:42

par Rockleader » 07 Jan 2014, 14:53

En rajoutant puts(tab) il m'écrit cou sans les espaces qui sont censées être devant
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 18:42

par Rockleader » 07 Jan 2014, 15:21

J'ai fini par le faire fonctionner au sein d'une même fonction;

maintenant j'aimerais arriver à séparer tout ça; une fonction permettant d'écrire et une d'afficher

Code: Tout sélectionner
void write_blocks(int pos,FILE* disk_id)
{
   fseek(disk_id,BLOCK_SIZE,pos);
   char block[BLOCK_SIZE]={0};
   printf("Quel block voulez vous entrer:");
   scanf("%s",block);
   fwrite( block , sizeof(block[0]) , sizeof(block)/sizeof(block[0]) , disk_id);
}


Code: Tout sélectionner
void read_block(int pos,FILE* disk_id)
{
   if (disk_id != NULL)
      {
         char block[BLOCK_SIZE]={0};
         fseek(disk_id,BLOCK_SIZE,pos);
         fread( block , sizeof(block[0]) , sizeof(block)/sizeof(block[0]) , disk_id);
         puts(block);
      }
}


Sa compile mais je suis pas sur d'employer la bonne méthodes; les valeurs sont en fait stocké dans block par fread puis affiché par puts ?
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Avatar de l’utilisateur
ampholyte
Membre Transcendant
Messages: 3940
Enregistré le: 21 Juil 2012, 07:03

par ampholyte » 07 Jan 2014, 15:37

Rockleader a écrit:Sa compile mais je suis pas sur d'employer la bonne méthodes; les valeurs sont en fait stocké dans block par fread puis affiché par puts ?


Tout à fait, la fonction puts est équivalente à
Code: Tout sélectionner
fprintf(stdout,"%s\n", ma_chaine)

 

Retourner vers ϟ Informatique

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 9 invités

Tu pars déja ?



Fais toi aider gratuitement sur Maths-forum !

Créé un compte en 1 minute et pose ta question dans le forum ;-)
Inscription gratuite

Identification

Pas encore inscrit ?

Ou identifiez-vous :

Inscription gratuite