modifier le contenu existant de fichier en c
int main()
{
FILE *ft;
char ch;
ft=fopen("abc.txt","r+");
if(ft==NULL)
{
printf("can not open target file\n");
exit(1);
}
while(1)
{
ch=fgetc(ft);
if(ch==EOF)
{
printf("done");
break;
}
if(ch=='i')
{
fputc('a',ft);
}
}
fclose(ft);
return 0;
}
Comme on peut le voir que je veux modifier abc.txt
de telle manière que i
est remplacé par a
.
Le programme fonctionne très bien mais quand j'ai ouvert abc.txt
de l'extérieur, il semblait être modifiée.
Toute raison possible pour que?
Pourquoi, dans ce cas, le caractère après i
n'est pas le remplacer par a
, car les réponses suggèrent?
Essayez
fclose(ft) avant de retourner.
fflush()
-ing le descripteur peut-être...fclose(ft) avant de retourner.
fgetc()
retourne un int
, pas un char
; elle doit retourner chaque valable char
valeur, majorée d'une valeur individuelle, les expressions du FOLKLORE. Comme l'écrit, vous ne pouvez pas détecter de manière fiable des expressions du FOLKLORE. Si char
est un type non signé, vous ne trouverez pas d'expressions du FOLKLORE; si char
est un type signé, vous aurez classifier certains caractères valide (souvent ÿ, y tréma, U+00FF, la LETTRE minuscule LATINE Y TRÉMA) comme des expressions du FOLKLORE.OriginalL'auteur zee | 2014-02-22
Vous devez vous connecter pour publier un commentaire.
Analyse
Il y a plusieurs problèmes:
fgetc()
retourne unint
, pas unchar
; elle doit retourner chaque valablechar
valeur, majorée d'une valeur individuelle, les expressions du FOLKLORE. Comme l'écrit, vous ne pouvez pas détecter de manière fiable des expressions du FOLKLORE. Sichar
est un type non signé, vous ne trouverez pas d'expressions du FOLKLORE; sichar
est un type signé, vous aurez classifier certains caractères valide (souvent ÿ, y tréma, U+00FF, la LETTRE minuscule LATINE Y TRÉMA) comme des expressions du FOLKLORE.Si vous basculez entre l'entrée et la sortie sur un fichier ouvert pour le mode de mise à jour, vous devez utiliser un fichier de positionnement de l'opération (
fseek()
,rewind()
, nominalementfsetpos()
) entre la lecture et l'écriture; et vous devez utiliser un positionnement opération oufflush()
entre l'écriture et de la lecture.C'est une bonne idée de fermer ce que vous ouvrez (maintenant corrigé dans le code).
Si votre écrit travaillé, vous souhaitez remplacer le caractère après le
i
aveca
.Synthèse
Ces changements conduisent à:
Il n'y a plus de place pour la vérification d'erreur.
L'exégèse
Entrée, suivie par la production nécessite cherche
La
fseek(ft, 0, SEEK_CUR);
déclaration est requise par la norme.(Italiques ajoutés.)
fgetc()
retourne unint
Des citations de la norme ISO/IEC 9899:2011, le C standard.
Donc,
EOF
est un entier négatif (généralement, il est de -1, mais la norme n'exige pas que). Lefgetc()
fonction retourne EOF ou la valeur du caractère deunsigned char
(dans l'intervalle 0..UCHAR_MAX, généralement 0..255).Ce qui justifie mon affirmation que la plaine
char
peut être signé ou d'un type non signé.Considérons maintenant:
Supposons que
fgetc()
retourne EOF, et la plainechar
est un entier non signé (8 bits), et des expressions du FOLKLORE est-1
. La mission met la valeur 0xFF dansc
, qui est un entier positif. Lorsque la comparaison est faite,c
est promue à unint
(et donc à la valeur 255), et 255 n'est pas négatif, de sorte que la comparaison échoue.Inversement, supposons que la plaine
char
est une signature (8 bits) type et le jeu de caractères ISO 8859-15. Sifgetc()
retourne ÿ, la valeur attribuée sera le motif de bits 0b11111111, qui est le même que-1
, donc dans la comparaison,c
seront convertis en-1
et la comparaisonc == EOF
sera de retour, même si l'un caractère valide a été lu.Vous pouvez affiner les détails, mais l'argument de base demeure valide pendant
sizeof(char) < sizeof(int)
. Il y a des puces DSP où ça ne s'applique pas; vous avez de repenser les règles. De même, le point de base reste;fgetc()
retourne unint
, pas unchar
.Si vos données est vraiment ASCII (7 bits de données), tous les personnages sont dans l'intervalle 0..127 et vous ne rencontrerez pas de la mauvaise interprétation de ÿ problème. Toutefois, si votre
char
est de type non signé, vous avez encore le 'ne peut pas détecter les expressions du FOLKLORE" problème, de sorte que votre programme va s'exécuter pendant un long moment. Si vous devez tenir compte de la portabilité, vous allez prendre cela en compte. Ce sont de qualité professionnelle, les questions que vous avez besoin pour gérer en tant que programmeur C. Vous pouvez bidouille votre façon de programmes qui fonctionnent sur votre système, vos données relativement facilement et sans prendre toutes ces nuances en compte. Mais votre programme ne fonctionne pas sur d'autres systèmes.fseek(ft, 0, SEEK_CUR);
Cette ligne est de ne rien faire et qu'il n'est pas nécessaire.contraire. La norme exige un positionnement entre une lecture et une opération d'écriture sur une mise à jour de flux, ou entre une écriture et une lecture. C'est une opération de positionnement entre une écriture et une lecture. Il est pas no-op; il place le filet dans un mode qui permet la prochaine
fgetc()
de travailler correctement, de manière fiable, sur les plates-formes, comme requis par la norme.Vérifier ceci, il dit: "Notez que le C ANSI exige qu'une fonction de positionnement de fichier intervenir entre la sortie et l'entrée, à moins qu'une opération d'entrée de rencontres de fin de fichier.'
7e Édition Unix seulement eu
"r"
,"w"
, et"a"
modes en 1979. Cependant, la première édition de la norme (1989) a étendu les modes (leb
modificateur, et la+
les modes), et je pense que le+
modes ont été disponibles plus tôt.n'est pas un personnage! Par conséquent, il doit être de de
char
. C'est une valeur de signal que pas plus de caractères peut être lu à partir d'un flux.OriginalL'auteur Jonathan Leffler
Vous ne modifiez pas le " je "en
abc.txt
, vous sont en train de changer le caractère suivant après "je". Essayez de mettrefseek(ft, -1, SEEK_CUR);
avant votrefputc('a', ft);
.Après avoir lu un 'i', le fichier indicateur de position de
ft
sera le personnage après ce "je", et quand vous écrivez un personnage parfputc()
, ce personnage sera d'écrire à la position courante dans le fichier, c'est à dire le caractère après le "je". Voirfseek(3)
pour plus de détails.fseek(ft, -1, SEEK_CUR);
, la boucle tourne à l'infini.Non, il ne le sera pas.
oups désolé...c'était une autre erreur
parce que la norme dit que vous avez besoin, et parce qu'elle ne fonctionne pas quand vous ne le faites pas. Comment beaucoup plus de raisons avez-vous besoin?
En général, le plus propre dispositions de la norme C est là parce qu'un système ou l'autre a de la difficulté à gérer les choses si la prestation n'a pas été fait. Pour un exemple extrême, voir les restrictions sur la façon dont vous pouvez utiliser la
setjmp()
macro à partir de<setjmp.h>
. Plus proche de l'actualité, il y a des restrictions sur ce qui se passe avec les fichiers texte (espaces à droite, la finale de saut de ligne), il est possible pour les systèmes de respecter la norme qui, autrement, ne pourraient pas. Dans ce cas, je ne suis pas sûr de tous les tenants et les aboutissants, mais il rend l'application plus facile. Rappelez-vous il y aungetc()
à manipuler trop.OriginalL'auteur Lee Duhem
Après la lecture de " je " vous avez besoin de "pas en arrière" pour l'écriture à l'emplacement correct.
fseek()
opération après lefputc()
selon la norme C — voir ma réponse pour les citations de la norme.OriginalL'auteur OregonTrail