IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Problème read / write


Sujet :

C

  1. #1
    Membre expérimenté Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    623
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 623
    Points : 1 554
    Points
    1 554
    Par défaut Problème read / write
    Bonjour à tous,

    Je fais appel appel à vos lumières pour le motif suivant: je souhaite inverser un fichier, càd que le dernier octet devient le premier, etc, jusqu'au premier qui devient le dernier, et ce quelque soit le type de fichier en entrée.
    Le programme ne se plante pas, mais si je le teste avec un fichier binaire (un mp3 par ex.) dont la taille d'entrée est de 26Mb, le fichier en sortie ne contient que 13Mb (la moitié, mais c'est par hasard).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
     
    #define BUFLEN 4096
     
    /* fout, fin : descripteurs fichiers sortie et entrée */
    void reverse(int fout,int fin)
    {
    	unsigned char bufin[BUFLEN],bufout[BUFLEN];
    	unsigned char *pi,*po;
    	int sstop=0;
    	long pseek,rlen=BUFLEN;
     
    	pseek=filelength(fin)-BUFLEN-1; /* -1:filelength() compte aussi EOF */ /* Provisoire */
    	if(pseek<0l) {
    		rlen=BUFLEN+pseek;
    		pseek=0l;
    		sstop=1;
    		}
    	printf("Processing .");
    	lseek(fin,pseek,SEEK_SET);
    	while(sstop<2) {
    		read(fin,bufin,(unsigned)rlen); 
    		setmem(bufout,BUFLEN,0);
    		pi=bufin+(unsigned)rlen-1;
    		po=bufout;
    		while(pi>=bufin) *po++=*pi--;
    		write(fout,bufout,(unsigned)rlen);
    		pseek-=2l*BUFLEN;
    		if(pseek<0l) {
    			rlen=BUFLEN+pseek;
    			pseek=0l;
    			sstop++;
    			}
    		if(sstop<2) {
    			putchar('.');
    			lseek(fin,pseek,SEEK_SET);
    			}
    		}
    	printf("\n");
    }
     
    void main(int argc,char *argv[])
    {
    	int fhin,fhout;
    	char tmp[80];
    	fhin=open(argv[1],O_BINARY|O_RDONLY,S_IREAD|S_IWRITE);
    	fhout=open(argv[2],O_BINARY|O_WRONLY|O_CREAT|O_TRUNC,S_IREAD|S_IWRITE);
    	reverse(fhout,fhin);
    	close(fhout);
    	close(fhin);
    }
    Je passe sur tous les contrôles que j'ai retirés pour faire court.

    Merci de m'aider,
    Edgar.
    On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent

  2. #2
    Expert confirmé Avatar de fregolo52
    Homme Profil pro
    Développeur C
    Inscrit en
    Août 2004
    Messages
    2 364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Août 2004
    Messages : 2 364
    Points : 5 378
    Points
    5 378
    Par défaut
    tu peux m'expliquer le principe de ton algo (qui à l'air d'écrire par bloc de 4k) ?

    j'ai un peu de mal avec la variable pseek :
    pseek-=2l*BUFLEN;
    tu copies BUFLEN et après tu te décales de 2 fois cette taille !

    Je ne comprends pas ton critère d'arrêt. Pourquoi ne pas tester le fin du fichier ?

  3. #3
    Membre habitué
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    81
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 81
    Points : 128
    Points
    128
    Par défaut
    Apparemment, le décalage de pseek sert à repositionner le pointeur de lecture sur le fichier d'entrée de deux blocs (celui qu'on vient de lire et celui qu'on va lire).

  4. #4
    Membre expérimenté Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    623
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 623
    Points : 1 554
    Points
    1 554
    Par défaut
    Apparemment, le décalage de pseek sert à repositionner le pointeur de lecture sur le fichier d'entrée de deux blocs (celui qu'on vient de lire et celui qu'on va lire).
    @sam1507: tu as bien compris ce que je fais, ça recule la position courante du pointeur de deux blocs. J'ai encore (un peu) bossé dessus ce matin, je ne vois pas pourquoi j'ai ce problème.

    qui à l'air d'écrire par bloc de 4k
    Oui, ça c'est provisoire, un malloc() est prévu dans la version définitive.
    Le principe: je lis le dernier bloc du fichier d'entrée, j'inverse les octets et les écris, je recule mon pointeur de 2*(la taille d'un bloc), et on recommence le cycle, jusqu'à ce que le dernier bloc à lire soit plus petit que la taille BUFLEN.
    On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent

  5. #5
    Invité
    Invité(e)
    Par défaut
    EDIT :
    Comme l'a fait remarquer fregolo52, c'est une mauvaise solution qui suit, ne lisez pas. Désolé.

    Ta solution me paraît compliquée à première vue, est-ce qu'il ne serait pas plus simple de :
    - mapper le fichier en mémoire avec mmap
    - inverser les octets un à un dans une boucle grâce à deux compteurs, un qui partirait du début et l'autre de la fin, et ce jusqu'au moment où ils se rejoignent :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    int           fin;
    int           dbt;
    char        tmp;
     
    dbt = 0;
    fin = strlen(str) - 1;
    while (dbt <= fin)
       {
         tmp = str[dbt];
         str[dbt] = str[fin];
         str[fin] = tmp;
         fin--;
         dbt++;
     }
    Dernière modification par Invité ; 23/06/2011 à 10h52.

  6. #6
    Expert confirmé Avatar de fregolo52
    Homme Profil pro
    Développeur C
    Inscrit en
    Août 2004
    Messages
    2 364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Août 2004
    Messages : 2 364
    Points : 5 378
    Points
    5 378
    Par défaut
    C'est quoi cette horreur !!!
    edgarjacobs donne un exemple de fichier mp3, strlen est à banir !!!!

    Ta condition de "stop" est moche !! Utilise feof sur fin (ou le code de retour de la fonction read, c'est sûrement mieux) pour savoir si tu as fini de lire le fichier source.

Discussions similaires

  1. [MASM32][Débutant] Read / Write Console
    Par Jean Michou dans le forum x86 32-bits / 64-bits
    Réponses: 7
    Dernier message: 16/04/2008, 23h24
  2. probleme read write serveur/client
    Par romainromain dans le forum Réseau
    Réponses: 9
    Dernier message: 22/11/2006, 16h23
  3. propriété read write
    Par new_wave dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 08/09/2006, 11h24
  4. Problème document.write
    Par nek_kro_kvlt dans le forum Général JavaScript
    Réponses: 8
    Dernier message: 10/01/2006, 20h13
  5. Problème de read/write
    Par mylooz dans le forum Entrée/Sortie
    Réponses: 7
    Dernier message: 25/03/2005, 19h15

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo