clseek

Trouble working with file using lseek() read() and write()


i'm working on C in my university, i'm at the beggining working with buffers and this function so apolagize my lack of knowledge that i might show. I gotta do this project using lseek(), write() and read(). I wanted to read a file, and every letter 'a' that i find i would change it to '?'. My code so far is:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>

int main () {
  int fd = open("problema4file", O_RDWR);
  int fptr = lseek(fd, (off_t)(-1), SEEK_END);
  char buffer;
  while(fptr!=-1){
    read(fd, &buffer, 1);
    char changeTo = '?';
    if(buffer == 'a'){
       write(fd, &changeTo,1);
    }
    fptr=lseek(fd, (off_t)(-2), SEEK_CUR);
  }
  close(fd);
}

But this changed the first 'a' (last, because i start from the end) and no more. It stops changing. Oh and it doesn't change the 'a', changes the letter after, but that has to do with the buffer movements right? i might think about that later.. I just wanted to know why this doesn't read all the file and changes everything, it stops in the first finding.


Solution

  • You read a byte and then write a byte without repositioning the offset within the file. Then you seek backwards 2 positions.

    Write down what you're doing on a piece of paper to understand what's wrong.

    P.S. That last line - you should do that for everything you write from now until you don't write code anymore ;)

    you seek to EOF - 1, you're before the last byte in the file.  
    you read a byte, you're now at EOF.  
    Then you write a byte (you've extended the file by one), you're positioned again @ EOF.  
    you now seek backwards 2 bytes, which puts you back to where you began.