11
votes

Comment écraser une seule partie d'un fichier en C ++

Je veux apporter des modifications au milieu d'un fichier texte à l'aide de C ++, sans modifier le reste du fichier. Comment puis-je faire ça?


2 commentaires

Ce n'est pas un duplicata. Le message précédent n'était que sur la manière de lire un enregistrement, il s'agit d'écrire dans un fichier. Vous devez lire plus attentivement.


Votre élaboration que le remplacement est la même longueur fait la viande de la question de savoir comment repositionner le pointeur de fichier, ce qui correspond exactement à ce que les réponses à votre autre question fournies.


3 Réponses :


0
votes

En règle générale, ouvrez le fichier pour la lecture en mode texte, lecture de ligne après ligne jusqu'à ce que vous souhaitez modifier, tout en lisant les lignes, écrivez-les dans un deuxième fichier texte que vous avez ouvert à écrire. Sur place pour le changement, écrivez au deuxième fichier les nouvelles données. Continuez ensuite la lecture / écriture du fichier à sa fin.


1 commentaires

Je veux éviter de le faire de cette façon.



8
votes

Si la chaîne de remplacement est la même longueur, vous pouvez faire le changement de place. Si la chaîne de remplacement est plus courte, vous pourrez peut-être le rembourrer avec des espaces de largeur zéro ou similaire pour en faire le même nombre d'octets et faire le changement de place. Si la chaîne de remplacement est plus longue, il n'ya tout simplement pas assez de place que si vous déplacez d'abord toutes les données restantes.


6 commentaires

Cela semble bon, mais quel est le code pour cela? Supposons que la chaîne est la même longueur.


Eh bien, cela dépend de la bibliothèque d'E / S que vous utilisez, de la bibliothèque standard C, de la bibliothèque standard C ++ ou d'une API spécifique au système d'exploitation. Mais généralement, il y a trois étapes. Lors de l'ouverture du fichier, spécifiez l'accès en écriture sans troncature, par exemple. fopen (fname, "r +"). Cherchez à l'emplacement souhaité avec E.G. fsek. Écrivez la nouvelle chaîne avec E.G. fwrite ou fprintf. Dans certaines API, comme Windows chevauchée ou Linux AIO, vous pouvez dire «écrire à cet endroit» sans une étape de recherche séparée.


Fsek ne fonctionne pas avec Ofstream. Comment peut-on faire avec detream?


J'ai essayé la recherche et quand j'ai écrit au fichier, tout écrasé.


Ok, je vais mettre l'accent sur la partie de mon commentaire précédent "lors de l'ouverture du fichier, spécifiez l'accès en écriture sans troncature". De stdcxx.apache.org/doc/stdlibug/30-3.htmlle_/30- A>, pour les flux de fichiers de sortie Le mode ouvert est équivalent à l'extérieur | Trunc, c'est-à-dire que vous pouvez omettre le drapeau de trunc . Donc, utilisez un FRStream bidirectionnel au lieu d'un degré.


Heureux que vous soyez finalement arrivé là-bas. À l'avenir, vous obtiendrez une réponse plus rapide et avec beaucoup moins de frustration si vous nous dites: quelles bibliothèques, quel compilateur et si vous le souhaitez portable, ce que vous avez essayé jusqu'à présent, le comportement que vous voyez maintenant, et Ce que vous vouliez. Pour cette question, cela aurait aidé à dire «J'essaie d'écraser une seule partie d'un fichier à l'aide d'un dossier. Voici le code (vous avez réellement mis cela dans une autre question). Les nouvelles données apparaissent dans le fichier, mais non Peu importe ce que je fais le contenu précédent disparaissent. Comment puis-je faire des modifications tout en conservant les autres parties du fichier. "



20
votes

Utilisez std :: fstream .

Le STD plus simple :: destream ne fonctionnerait pas. Il tronquerait votre fichier (sauf si vous utilisez l'option std :: ios_base :: app, ce qui n'est pas ce que vous voulez de toute façon). xxx


4 commentaires

Si vous utilisez le drapeau std :: ios_base :: ios_base :: binaire , n'oubliez pas que vous aurez besoin de ou de ceci avec std :: ios_base :: out


En utilisant std :: ios_base :: binaire | STD :: iOS_BASE :: OUT Les indicateurs de mode provoquent la troncature après les données écrites dans le fichier. En utilisant std :: ios_base :: binaire | std :: ios_base :: out | std :: ios_base :: in empêche cela.


Donc, est-ce que je avez pour ouvrir le fichier pour la lecture et l'écriture pour modifier une partie du fichier, même si je ne lire de celui-ci? Est-il possible de modifier (ne pas ajouter) avec uniquement l'accès à l'écriture sans écraser tout? Peut-être que Fseek lui-même exige que le fichier soit ouvert à la lecture, même si Fread n'est pas utilisé? (Bien que cela me semble étrange), enfin, est-ce une limitation du système d'exploitation, ou simplement la manière dont la bibliothèque C ++ standard fonctionne?


@ QBERT220 Votre commentaire est si précieux, c'est très utile pour moi. J'ai eu le même problème que chaque fois que j'ai essayé d'écrire un coffre de données dans un fichier, il a remplacé le fichier entier, ce qui me fait gratter ma tête jusqu'à ce que j'ai trouvé votre commentaire. Merci mon pote