2010-10-18 43 views
1

J'ai un fichier binaire au format CSV qui contient plusieurs enregistrements. Chaque enregistrement est entré en tant que nom_utilisateur, nom_famille, prénom, num_wins, num_losses, num_ties. Je suis en train de créer une méthode pour mettre à jour un certain nombre de victoires, de pertes et de liens. L'utilisateur entre le nom d'utilisateur à changer suivi par les changements aux victoires, pertes et liens. Par exemple smithj 4 5 1. Ceci trouvera l'enregistrement smithj et ajoutera 4 aux victoires etc.C Programme: Comment utiliser correctement lseek() ou fseek() pour modifier une certaine partie d'un fichier?

Comment utiliser lseek ou fseek pour accomplir ceci? Ou est-ce qu'il y a un autre moyen de le faire?

+2

C'est l'abréviation de Comma Separated Value. Quoi qu'il en soit, lseek et fseek ne vont pas sauter au bon endroit à moins que vous sachiez où cela se trouve. En outre, si vous augmentez la taille de l'enregistrement (par exemple lorsque vous ajoutez 1 à 9 et obtenez 10), vous allez avoir des problèmes. – xscott

+0

Si vous avez besoin de coller avec le format CSV, je prévois de lire le fichier ligne par ligne et de l'écrire ligne par ligne. Lorsque vous en trouvez un qui correspond, vous pouvez le modifier le cas échéant. – xscott

+0

Ce genre de problème est vraiment résolu beaucoup plus facilement avec un vrai format de base de données. Je recommande Sqlite. Cependant, ce sera un peu une courbe d'apprentissage si vous commencez tout juste. – xscott

Répondre

1

Réponse à la demande d'écriture d'exemple - en supposant des enregistrements de taille fixe:

enum { RECSIZE = 256 }; 

char buffer[RECSIZE]; 
FILE *fp = ...; // File to read from and write to 

int recnum = 37; // Counting from record 0 
long offset = recnum * RECSIZE; 

if (fseek(fp, offset, SEEK_SET) != 0) 
    ...error... 
if (fread(buffer, sizeof(buffer), 1, fp) != 1) 
    ...error... 
...modify buffer... 
if (fseek(fp, offset, SEEK_SET) != 0) 
    ...error... 
if (fwrite(buffer, sizeof(buffer), 1, fp) != 1) 
    ...error... 

Répétez le code de la déclaration de recnum à la fin une fois pour chaque enregistrement qui doit être modifié (boucle penser). Avec les enregistrements de taille variable qui changent de taille au fur et à mesure que vous les modifiez, vous devez travailler beaucoup plus fort - de sorte qu'il est probablement plus simple de copier l'ancien fichier en mémoire un enregistrement à la fois, en modifiant l'enregistrement de manière appropriée. puis en écrivant l'enregistrement modifié dans un nouveau fichier. CSV contient généralement du texte en clair.

1

En supposant que le fichier est un fichier texte, vous devrez remplir les lignes à une largeur constante. Utilisez ensuite lseek(), read() et write() pour modifier les lignes. Avoir une longueur constante pour chaque ligne est crucial: cela vous permet de calculer la position de départ de chaque ligne.

1

C'est assez facile à faire si chaque enregistrement a le même nombre d'octets. Vous vérifiez le premier enregistrement pour voir si c'est une correspondance, et sinon, faites fseek(f, record_size, SEEK_CUR); et vérifiez l'enregistrement suivant.

Si chaque enregistrement doit être un nombre différent d'octets, tout ce que je peux penser est que vous mettez le nombre d'octets que l'enregistrement est avant l'enregistrement réel. Et puis lisez cela dans, puis fseek() que de nombreux octets pour atteindre la taille d'enregistrement suivante. J'ai vu certains formats de fichiers binaires faire cela, ce qui rend les choses assez faciles.

+1

Vous devez lire aussi bien que chercher - ou, plus généralement, vous lisez jusqu'à ce que vous trouviez, puis rembobinez (avec fseek()) au début de l'enregistrement afin que vous puissiez l'écraser. Si vous ne lisez qu'une partie de l'enregistrement, vous devrez peut-être effectuer une recherche entre les lectures. Cependant, le lecteur de disque sera probablement lu en morceaux de 4096 octets (une puissance de 2 entre 512 octets et environ 16 KiB) et à moins que votre enregistrement soit extraordinairement long, vous n'aurez qu'à mélanger des données dans votre programme en lisant moins que le dossier complet; le trafic disque réel ne sera pas affecté par des lectures partielles d'enregistrements. –

+0

Serait-il possible pour quelqu'un d'écrire un exemple de comment faire cela? –