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 :

Lecture d'un fichier octet par octet


Sujet :

C

  1. #1
    Yux
    Yux est déconnecté
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    105
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2004
    Messages : 105
    Points : 74
    Points
    74
    Par défaut Lecture d'un fichier octet par octet
    Salut,

    Je pratique le c depuis peu (pour le plaisir ) et je cherche à implémenter un petit programme de compression utilisant l'algorithme de huffman.

    J'ai écrit le code suivant :

    huffman.h

    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
    #ifndef __HUFFMAN_H
    #define __HUFFMAN_H
     
    #include "huffman.h"
     
    void parser (const char *f, unsigned long int t[256])
    {
    	FILE *fp;
    	char buffer;
    	if ((fp = fopen (f, "r")) == NULL)
    	{
    		fprintf (stderr, "Echec de l'ouverture du fichier %s", f);
    		perror (" ");
    		exit (1);
    	}
    	while (1)
    	{
    		if (fread (& buffer, sizeof (char), 1, fp) == 1)
    		{
    			t[buffer]++;
    		}
    		else
    		{
    			break;
    		}
    	}	
    	fclose (fp);
    }
     
    #endif /* __HUFFMAN_H */
    huffman.c

    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
    #include<stdio.h>
    #include<stdlib.h>
    #include "huffman.h"
     
    const char *file;
    unsigned long int tab[256];
     
    int main (int argc, char *argv[])
    {
    	file = argv[1];
    	int i;
    	for (i=0 ; i<256 ; i++)
    	{
    		tab[i]=0;
    	}
    	parser (file, tab);
    }
    Comme vous pouvez le constater, j'en suis simplement à la phase initiale (calcul des occurences de chaque octet).

    En fait, je ne sais pas si je procède de la meilleure des façons : venant du perl, je ne suis pas habitué à manipuler les types de données. Ici, j'ai défini un buffer de type char (pour y stocker un octet), mais je ne sais pas d'une part si je récupère une valeur décimale avec fread, et d'autre part si l'écriture :

    est valable, ou si je dois réaliser un cast de la sorte :

    En tout cas, j'ai testé cette dernière solution qui n'a pas eu l'air de heurter gcc

    Pour terminer, j'ai écrit ça pour valider le fonctionnement de mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    	for (i=0 ; i<256 ; i++)
    	{
    		if (tab[i] != 0)
    		{
    			printf ("Indice : %d, valeur : %d\n", i, tab[i]);
    		}
    	}
    	return (0);
    Et je me tape une vielle erreur de segmentation, ça fonctionne juste si je conserve la première partie du printf comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf ("Indice : %d\n", i);
    A ce moment là, j'obtiens ça :

    Indice : 10
    Indice : 32
    Indice : 38
    Indice : 45
    Indice : 46
    Indice : 47
    Indice : 48
    Indice : 49
    Indice : 50
    Indice : 51
    Indice : 52
    Indice : 53
    Indice : 54
    Indice : 56
    Indice : 58
    Indice : 60
    Indice : 61
    Indice : 62
    Indice : 67
    Indice : 71
    Indice : 95
    Indice : 97
    Indice : 98
    Indice : 99
    Indice : 100
    Indice : 101
    Indice : 102
    Indice : 103
    Indice : 104
    Indice : 105
    Indice : 107
    Indice : 108
    Indice : 109
    Indice : 110
    Indice : 111
    Indice : 112
    Indice : 113
    Indice : 114
    Indice : 115
    Indice : 116
    Indice : 117
    Indice : 118
    Indice : 119
    Indice : 120
    Indice : 122
    Houla, je viens de me rendre que le code plante si je lui passe autre chose qu'un fichier texte en argument, je crois qu'il y a du boulot en perspective... Si une âme charitable pouvait me donner quelques indications, j'aimerais vraiment progresser en c !

    Merci d'avance pour vos réponses.

  2. #2
    Membre averti Avatar de Goundy
    Profil pro
    Étudiant
    Inscrit en
    Avril 2005
    Messages
    605
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2005
    Messages : 605
    Points : 386
    Points
    386
    Par défaut
    Bonsoir,
    Ce n'est pas trop pour t'aider mais enfait j'ai un code source C sur un DE/COmpresseur utilisant le code de huffman, si tu veux l'inspécter pour en tirer une idea, jte passe le lien

  3. #3
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    en fait, le cast n'est pas le mon: je dirais t[(unsigned char)buffer]
    ainsi, il n'y aura pas d'indices négatifs.

    De plus, je te conseille d'ouvrir le fichier en mode binaire ("rb") plutôt qu'en mode texte, puisque c'est pour travailler en octet par octet...

  4. #4
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut Re: Lecture d'un fichier octet par octet
    Citation Envoyé par Yux
    Je pratique le c depuis peu et je cherche à implémenter un petit programme de compression utilisant l'algorithme de huffman.
    C'est pas vraiment ce qu'il y a de plus simple...
    J'ai écrit le code suivant :

    huffman.h

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #ifndef __HUFFMAN_H
    #define __HUFFMAN_H
    Non. Tu n'es pas implémenteur.

    http://emmanuel-delahaye.developpez....htm#id_reserve
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    #include "huffman.h"
     
    void parser (const char *f, unsigned long int t[256])
    Ce '256' a une valeur documentaire, mais pas fonctionelle.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void parser (const char *f, unsigned long int t[])
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    {
    	FILE *fp;
    	char buffer;
    	if ((fp = fopen (f, "r")) == NULL)
    Attention, mode texte. Ne fonctionne que si le fichier est du texte pur. Sinon, mode binaire (0-255).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    	{
    		fprintf (stderr, "Echec de l'ouverture du fichier %s", f);
    		perror (" ");
    		exit (1);
    	}
    	while (1)
    	{
    		if (fread (& buffer, sizeof (char), 1, fp) == 1)
    Tordu. fgetc() suffit largement...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    		{
    			t[buffer]++;
    		}
    		else
    		{
    			break;
    		}
    	}	
    	fclose (fp);
    }
     
    #endif /* __HUFFMAN_H */
    [/code]
    Hein, quoi ? Du code dans un header ? Ne refais jamais ça!

    http://emmanuel-delahaye.developpez.com/codage.htm

  5. #5
    Yux
    Yux est déconnecté
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    105
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2004
    Messages : 105
    Points : 74
    Points
    74
    Par défaut
    Waouh, quelle réactivité ! Merci pour vos réponses...

    Emmanuel, merci en particulier pour tes liens. Ton site a l'air de contenir exactement ce dont j'ai besoin. Après une brève première lecture et en tenant compte de vos réponses, j'ai transformé mes deux fichiers en main.c, huffman.c, huffman.h :

    huffman.h :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #ifndef H_HUFFMAN
    #define H_HUFFMAN
     
    void parser (const char *f, unsigned long int a[]);
     
    #endif /* guard */
    huffman.c :

    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
    #include<stdio.h>
    #include<stdlib.h>
     
    #include "huffman.h"
     
    void parser (const char *f, unsigned long int a[])
    {
    	FILE *fp;
    	int i;
     
    	if ((fp = fopen (f, "rb")) == NULL)
    	{
    		fprintf (stderr, "Echec de l'ouverture du fichier %s", f);
    		perror (" ");
    		exit (1);
    	}
    	while ((i = fgetc (fp)) != EOF)
    	{
    		a[i]++;
    	}
    	fclose (fp);
    }
    Et enfin main.c :

    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
    #include<stdio.h>
     
    #include "huffman.h"
     
    const char *file;
    unsigned long int array[256];
     
    int main (int argc, char *argv[])
    {
    	file = argv[1];
    	int i;
    	for (i=0 ; i<256 ; i++)
    	{
    		array[i]=0;
    	}
    	parser (file, array);
    	return (0);
    }
    Par contre, je bloque toujours sur la boucle destinée à afficher le contenu du tableau. Avec ce code (dans main.c) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for (i=0 ; i<256 ; i++)
    	{
    		fprintf ("Indice : %d, valeur : %d\n", i, array[i]);
    	}
    J'obtiens ces warnings :

    main.c: In function 'main':
    main.c:19: warning: passing argument 1 of 'fprintf' from incompatible pointer type
    main.c:19: warning: passing argument 2 of 'fprintf' makes pointer from integer without a cast
    Qu'est-ce-que cela signifie, que fprintf ne prend que des pointeurs en argument ? Il me semblait bien avoir utilisé cette fonction de cette façon par le passé...

  6. #6
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Yux
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    		fprintf ("Indice : %d, valeur : %d\n", i, array[i]);
    main.c: In function 'main':
    main.c:19: warning: passing argument 1 of 'fprintf' from incompatible pointer type
    main.c:19: warning: passing argument 2 of 'fprintf' makes pointer from integer without a cast
    Qu'est-ce-que cela signifie, que fprintf ne prend que des pointeurs en argument ? Il me semblait bien avoir utilisé cette fonction de cette façon par le passé...
    Relis ton livre de C. Le premier argument de fprintf() n'est pas ce que tu crois, ou alors tu confonds printf() et fprintf()...

  7. #7
    Membre éprouvé

    Profil pro
    Inscrit en
    Août 2003
    Messages
    878
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 878
    Points : 1 067
    Points
    1 067
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #include <stdio.h>
    int fprintf (FILE *stream, const char *format, ...);

  8. #8
    Yux
    Yux est déconnecté
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    105
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2004
    Messages : 105
    Points : 74
    Points
    74
    Par défaut
    Le premier argument de fprintf() n'est pas ce que tu crois, ou alors tu confonds printf() et fprintf().
    Effectivement... Merci encore pour vos réponses, je passe le topic en résolu.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Lecture d'un fichier octet par octet
    Par oranoutan dans le forum C
    Réponses: 2
    Dernier message: 12/07/2008, 16h30
  2. Lecture d'un fichier .wav octet par octet
    Par DevVB dans le forum VB 6 et antérieur
    Réponses: 7
    Dernier message: 27/07/2007, 12h10
  3. [Java 1.4] : lecture d'un fichier octet par octet
    Par Thi0123 dans le forum Entrée/Sortie
    Réponses: 10
    Dernier message: 08/06/2007, 21h29
  4. [Gestion de fichiers] Lecture octet par octet
    Par kendras dans le forum C
    Réponses: 21
    Dernier message: 18/09/2006, 15h08
  5. Lecture d'un fichier octet par octet
    Par PopKoRn...X_x dans le forum C++
    Réponses: 10
    Dernier message: 01/07/2005, 19h09

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