Parser un fichier binaire en C

damien_t

Membre actif
21 Juin 2004
295
13
45
Bonjour,
J'ai commencé un petit logiciel de lecteur audio en Objective-C. Tout va bien, je me débrouille. Le problème, c'est que je dois lire des données binaires qui ne sont pas produites par mon logiciel (techniquement ce sont les enregistrements d'une liste de lecture intelligente d'iTunes). Je connais le format des données et je voudrais transformer ce que je lis en nombres exploitables. J'ai l'algorithme en tête, mais je ne sais absolument pas comment le faire en C pur (ni en Objective-C pour le coup).

En fait, pour simplifier le problème, je dois boucler, et récupérer mes nombres par paquets de 32bit (ou par groupe de 4 octets) et prendre des décisions suivant le nombre que je trouve.

Par exemple dans le code suivant, je voudrais récupèrer le premier et le troisième 0x0001, le 0x0044 et le 0x0017 et ignorer le reste.

Bloc de code:
0000000 534c 7374 0001 0001 0000 0001 0000 0000
0000010 0000 0000 0000 0000 0000 0000 0000 0000
*
0000080 0000 0000 0000 0000 0000 0017 0000 0200
0000090 0000 0000 0000 0000 0000 0000 0000 0000
*
00000b0 0000 0000 0000 0000 0000 0000 0000 0044
00000c0 2dae 2dae 2dae 2dae ffff ffff ffff ffff
00000d0 0000 0000 0001 5180 2dae 2dae 2dae 2dae
00000e0 0000 0000 0000 0000 0000 0000 0000 0001
00000f0 0000 0000 0000 0000 0000 0000 0000 0000
J'ai dépoussiéré mon K&R, lu tout ce que je pouvais sur le net, mais je sèche toujours.
Si quelqu'un pouvais m'indiquer la bonne direction, ça serait super sympa.

merci d'avance
 
Bonjour,
J'ai commencé un petit logiciel de lecteur audio en Objective-C. Tout va bien, je me débrouille. Le problème, c'est que je dois lire des données binaires qui ne sont pas produites par mon logiciel (techniquement ce sont les enregistrements d'une liste de lecture intelligente d'iTunes). Je connais le format des données et je voudrais transformer ce que je lis en nombres exploitables. J'ai l'algorithme en tête, mais je ne sais absolument pas comment le faire en C pur (ni en Objective-C pour le coup).

En fait, pour simplifier le problème, je dois boucler, et récupérer mes nombres par paquets de 32bit (ou par groupe de 4 octets) et prendre des décisions suivant le nombre que je trouve.

Par exemple dans le code suivant, je voudrais récupèrer le premier et le troisième 0x0001, le 0x0044 et le 0x0017 et ignorer le reste.

Bloc de code:
0000000 534c 7374 0001 0001 0000 0001 0000 0000
0000010 0000 0000 0000 0000 0000 0000 0000 0000
*
0000080 0000 0000 0000 0000 0000 0017 0000 0200
0000090 0000 0000 0000 0000 0000 0000 0000 0000
*
00000b0 0000 0000 0000 0000 0000 0000 0000 0044
00000c0 2dae 2dae 2dae 2dae ffff ffff ffff ffff
00000d0 0000 0000 0001 5180 2dae 2dae 2dae 2dae
00000e0 0000 0000 0000 0000 0000 0000 0000 0001
00000f0 0000 0000 0000 0000 0000 0000 0000 0000
J'ai dépoussiéré mon K&R, lu tout ce que je pouvais sur le net, mais je sèche toujours.
Si quelqu'un pouvais m'indiquer la bonne direction, ça serait super sympa.

merci d'avance
Le fichier à l'air d'être très structuré, peut-être que la solution à ton problème est de parser le fichier avec des expressions rationelles.

http://www.gnu.org/software/libc/manual/html_node/Regular-Expressions.html#Regular-Expressions

:)
 
Façon C : la fonction fread de la librairie C standard.
C'était justement cette fonction que je ne comprenais pas. Ca faisait longtemps que je n'avais pas écrit de C et j'avais oublié à quel point c'était un language "dépouillé".

Façon Obj-C "objet" : les classes NSFileHandler et NSData.
Oui, merci, c'était bien ça. Je sais pas pourquoi cela fait plusieurs fois que je passe à coté de la doc Apple sur un point donné alors que j'ai cherché pendant des heures.

A titre informatif et pour les moteurs de recherche, j'ai collé ma solution un peu plus bas. La fonction magique que je cherchais était -NSData getBytes: (void *)buffer


Bloc de code:
#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    NSFileHandle *fh;
    NSData *wordBuffer;
    int currentValue;
    NSNumber *parsedValue;
    
    fh = [NSFileHandle fileHandleForReadingAtPath:@"/Users/damien/Desktop/smartinfo.bin"];
    while ((wordBuffer = [fh readDataOfLength:sizeof(int)]) && [wordBuffer length])
    {
    [wordBuffer getBytes: &currentValue];
    parsedValue = [NSNumber numberWithInt:currentValue];
        NSLog(@"word data as integer: %@",  parsedValue);
    }
    [pool release];
    return 0;
}

merci encore