3 votes

Est-ce que `fseek`, `fsetpos` et `rewind` vident le tampon en C?

La référence C indique qu'un FILE* ouvert en mode mise à jour ('+') doit prendre les deux précautions suivantes :

  • Une sortie ne peut pas être suivie d'une entrée sans un appel à l'une des fonctions fflush, fseek, fsetpos ou rewind.
  • Une entrée ne peut pas être suivie d'une sortie sans un appel à l'une des fonctions fseek, fsetpos ou rewind.

J'ai appris que fflush suffit pour permettre une entrée après une sortie, car un FILE* ouvert en mode + utilise souvent le même tampon pour les opérations de lecture et d'écriture. Par conséquent, ne pas utiliser fflush avant une entrée pourrait entraîner la lecture erronée de données du tampon (qui n'aurait peut-être pas été vidé, et contient donc des données qui doivent encore être écrites).

Cependant, pour que fseek, fsetpos et rewind obtiennent le même effet, cela implique qu'ils doivent vider internement le tampon du flux qui leur est passé.

Est-ce que la norme C exige que fseek, fsetpos et rewind vident le tampon de leurs flux ? Sinon, pourquoi pas ?

0voto

chux Points 13185

À titre de référence uniquement

Lorsqu'un fichier est ouvert en mode de mise à jour ('+' comme deuxième ou troisième caractère dans la liste ci-dessus des valeurs d'argument de mode), à la fois une entrée et une sortie peuvent être effectuées sur le flux associé. Cependant, la sortie ne doit pas être directement suivie par une entrée sans un appel intermédiaire à la fonction fflush ou à une fonction de positionnement de fichier (fseek, fsetpos, ou rewind), et l'entrée ne doit pas être directement suivie par une sortie sans un appel intermédiaire à une fonction de positionnement de fichier, à moins que l'opération d'entrée ne rencontre la fin de fichier. Ouvrir (ou créer) un fichier texte en mode de mise à jour peut plutôt ouvrir (ou créer) un flux binaire dans certaines implémentations.
C23dr § 7.23.5.3 7

0voto

Nate Eldredge Points 2185

En cherchant "flush" dans la norme C17, les seules actions garanties pour vider le tampon sont fclose(), fflush(), exit() et le retour de main. De plus, il est défini par l'implémentation si abort() ou _Exit() effectuent un vidage. Il n'y a aucune indication que fseek() et ses homologues seraient garantis pour le faire.

L'exigence d'appeler fseek(), etc. est de permettre des implémentations stdio primitives qui ne suivent pas si la dernière opération était une lecture ou écriture, ni si et combien du tampon est sale. Mais une implémentation plus intelligente pourrait bien suivre. Dans ce cas, il n'y aurait pas besoin pour fseek() de vider, car le vidage serait effectué au besoin par les opérations de lecture/écriture ultérieures. Il n'y a aucune raison valable pour que la norme contrecarre de telles optimisations en exigeant un vidage là où ce n'est pas nécessaire.

Si le programmeur veut spécifiquement que le tampon soit vidé, il devrait simplement appeler fflush() plutôt que de compter sur la recherche pour le faire pour lui. Même si cela s'avère redondant sur une implémentation particulière, le coût supplémentaire devrait être négligeable, car vider un tampon déjà vide ne devrait rien faire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X