As mentioned above [by Andreas], you probably want r+
as the open mode.
Although you can use fread
[and fwrite
] with fseek
as suggested, I think fgetc
and fputc
would be simpler.
#include <stdio.h>
int
main(void)
{
long pos;
int chr;
FILE *pFile = fopen("example.txt", "r+");
while (1) {
chr = fgetc(pFile);
if (chr == EOF)
break;
if (chr == 'A') {
fseek(pFile,-1,SEEK_CUR);
fputc('B',pFile);
}
}
fclose(pFile);
return 0;
}
UPDATE:
Others have suggested using fread
, scanning the block, doing fseek
with a rewrite of the block using fwrite
.
For that, I'd just use open/read/write/lseek/close
or pread/pwrite
.
But, if we're going to go to that much trouble, as I mentioned in my top comments, I'd use mmap
. It's still pretty simple, and it is much faster than any of the aforementioned methods.
Anyway, here's the code:
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/mman.h>
int
main(void)
{
int fd;
struct stat st;
ssize_t remlen;
char *base;
char *cur;
char *end;
fd = open("example.txt",O_RDWR);
fstat(fd,&st);
base = mmap(NULL,st.st_size,PROT_READ | PROT_WRITE,MAP_SHARED,fd,0);
remlen = st.st_size;
cur = base;
end = &cur[remlen];
for (; remlen > 0; remlen = end - cur) {
cur = memchr(cur,'A',remlen);
if (cur == NULL)
break;
*cur++ = 'B';
}
munmap(base,st.st_size);
close(fd);
return 0;
}