2016-12-27 1 views
3

Je suis en train de lire un tas de valeurs binaires d'un fichier texte qui sont en binaire parce que je les ai stockées en utilisant fwrite. Le problème est que la première valeur du fichier est de 5 octets et que les 4800 suivantes ont une taille de 2 octets. Donc, quand j'essaie de parcourir le fichier et de lire les valeurs, cela me donne de mauvais résultats car mon programme ne sait pas qu'il devrait prendre 5 octets la première fois et ensuite 2 octets les 4800 restants.Comment lire des valeurs de bits de tailles différentes à partir d'un fichier?

Voici comment je suis à vélo dans le fichier:

long lSize; 
unsigned short * buffer; 
size_t result; 

pFile = fOpen("dataValues.txt", "rb"); 

lSize = ftell(pFile); 

buffer = (unsigned short *) malloc (sizeof(unsigned short)*lSize);  
size_t count = lSize/sizeof(short); 



for(size_t i = 0; i < count; ++i) 
{ 
    result = fread(buffer+i, sizeof(unsigned short), 1, pFile); 
    print("%u\n", buffer[i]); 
} 

Je suis sûr que je vais devoir changer ma déclaration fread parce que la première valeur est de type time_t donc je vais probablement besoin d'une déclaration qui ressemble à ceci:

result = fread(buffer+i, sizeof(time_t), 1, pFile); 

Cependant, cela n'a pas de travail quand je l'ai essayé et je pense qu'il est parce que je ne suis pas en train de changer la position de départ correctement. Je pense que pendant que je lis 5 octets de données, je ne bouge pas assez la position de départ.

Est-ce que quelqu'un ici a une bonne compréhension de fread? Pouvez-vous s'il vous plaît laissez-moi savoir ce que je peux changer pour que mon programme accomplisse ce dont j'ai besoin.

EDIT:

Voici comment j'écris au fichier.

fwrite(&timer, sizeof(timer), 1, pFile); 
fwrite(ptr, sizeof(unsigned short), rawData.size(), pFile); 

EDIT2:

J'ai essayé de lire le fichier en utilisant ifstream

int main() 
{ 
    time_t x; 
    ifstream infile; 
    infile.open("binaryValues.txt", ios::binary | ios::in); 
    infile.read((char *) &x, sizeof(x)); 
    return 0; 
} 

Cependant, maintenant il ne compile pas et me donner un tas d'erreurs undefined reference to code Je n'ai même pas écrit.

+0

Il peut être utile d'afficher le code utilisé pour stocker les données.Aussi lisez-vous ce fichier d'une autre machine qui l'a écrit? – Galik

+0

Pas même machine et j'ai ajouté le code 'fwrite'. C'est plutôt standard. Je prends juste quelques valeurs d'un QVector et les écris dans un fichier. –

+0

Le code utilisé pour stocker les données semble être C++? Donc, cela devrait être étiqueté C++? – cat

Répondre

0

Vous ne pouvez pas. Les flux sont des octets, presque toujours des octets (octets de 8 bits) orientés.

Vous pouvez facilement créer un flux orienté bits en plus de cela. Vous gardez juste quelques octets dans un tampon et gardez la trace du bit courant. Méfiez-vous des quelques derniers bits et tentez de combiner l'accès aux octets avec l'accès aux bits.

Untested mais c'est l'idée générale.

struct bitstream 
    { 
     unsigned long long rack; // 64 bits rack 
     FILE *fp;     // file opened for reading 
     int rackpos;    // 0 - 63, poisition of bits read. 
    } 

    int getbits(struct bitstream *bs, int Nbits) 
    { 
    unsigned long long mask = 0x8000 0000 0000 0000; 
    int answer = 0; 

    while(bs->rackpos > 8) 
    { 
     bs->rack <<= 8; 
     bs->rack |= fgetc(bs->fp); 
     bs->rackpos -= 8; 
    } 
    mask >>= bs->rackpos; 
    for(i=0;i<Nbits;i++) 
    { 
     answer <<= 1; 
     answer |= bs->rack & mask; 
     mask >>= 1; 
    } 
    bs->rackpos += Nbits; 

    return answer; 
    } 

Vous devez décider comment vous savez quand le flux est terminé. Comme vous allez corrompre les derniers bits avec l'EOF lu par fgetc().

+0

Désolé mais je suis un Noob C++ total, pouvez-vous expliquer ce que vous voulez dire? Est-ce qu'il y a encore un moyen pour moi d'accomplir ce dont j'ai besoin? Est-ce qu'il n'y a aucun moyen de distinguer une valeur 'time_t' d'une valeur' unsigned_short'? –

2

Je ne vois pas le problème:

uint8_t five_byte_buffer[5]; 
uint8_t two_byte_buffer[2]; 
//... 
ifstream my_file(/*...*/); 
my_file.read(&five_byte_buffer[0], 5); 
my_file.read(&two_byte_buffer[0], 2); 

Alors, quel est votre problème spécifique?

Edit 1: Lecture en boucle

while (my_file.read(&five_byte_buffer[0], 5)) 
{ 
    my_file.read(&two_byte_buffer[0], 5); 
    Process_Data(); 
} 
+0

Je n'ai pas compris votre message à quoi servent ces deux tableaux? Et pourquoi faites-vous 'my_file.read'? Je ne programme pas en C++ donc désolé si je suis stupide en ce moment. –

+0

Votre message indique que vous devez lire 5 octets, puis 2 octets. Les tampons contiennent les données que vous avez lues. –

+0

'my_file.read' est la méthode C++ pour lire des données non traitées d'un flux, dans ce cas, le flux' my_file'. –