ANSI C - fopen z r+, fputc, fgetc - co się na prawdę tam dzieje?

0

Witam

Chciałem napisać program, który co drugą literę zostawia a co drugą zmienia na znak @. Myślałem, że otwierając plik "r+" uzyskam prawa do odczytu i zapisu.
W pętli:

FILE *file = fopen ("test.txt","r+");
int n;
char c;
for(n = 0; n < 10; n++){
   if (i%2 == 0) fputc('@',file);
   else fgetc(file);
} 

Z tego co zrozumiałem, otworzy to plik na początku i strumień będzie przesuwany w prawo co każdą komendę. Jedna komenda zwyczajnie przeczyta znak i przesunie się w prawo, a następnie druga wpisze znak @ i też przesunie się w prawo.

O dziwo z pliku: "1234567890" produkuje plik: @@@@@

Możecie mi powiedzieć co tak na prawdę się stało bo nie rozumiem dlaczego znikło wszystko a pojawiło się tylko to.
Z góry dzięki

0

w kodzie oczywiście wkradła się literówka "i" to "n". Pytanie nadal aktualne

0

z kolei kod z lekką zmianą:

for (i = 0; i < 10; i++){
   if (i%2 == 0) fgetc(file);
   else fputc('@',file);
}

z plikiem nie robi nic. Nie są zapisywane żadne nowe znaki. Już nie kumam :(

0

Kolego standard dość wyraźnie opisuje tę sytuację:

When a file is opened with update mode ('+' as the second or third character in the above list of mode argument values), both input and output may be performed on the associated stream. However, output shall not be directly followed by input without an intervening call to the fflush function or to a file positioning function (fseek, fsetpos, or rewind), and input shall not be directly followed by output without an intervening call to a file positioning function, unless the input operation encounters end-of-file. Opening (or creating) a text file with update mode may instead open (or create) a binary stream in some implementations.

Może mało praktyczna odpowiedź ale wiesz już, w którym kierunku zmierzać - potem postaram się dorzucić przykład.

Edycja

#include<stdio.h>
int main() {
  FILE *file = fopen("testy.txt","r+");
  long int n;
  char c;

  for(n = 0; n < 10; n++) {
    if (n % 2 == 0) {
      fseek(file, n, SEEK_SET);  
      fputc('@', file); // Po dokonaniu zapisu trzeba wywołać jedną z funkcji pozycjonujących - to jest ten FSEEK() na dole.
    } else {
      fseek(file, n-1, SEEK_SET);
      fgetc(file); // Jeśli wykonywany jest odczyt to przed rozpoczęciem zapisu trzeba też użyć funkcji pozycjonującej - to jest ten FSEEK() na górze.
    }
  } 
  return 0;
}

Początkowa zawartość pliku:

1234567890

Po wykonaniu programu:

@2@4@6@8@0

0

Dziękuję Ci dobry człowieku.

Było to dla mnie bardzo pomocne.

1 użytkowników online, w tym zalogowanych: 0, gości: 1