tags:

views:

202

answers:

3

Let's say I have a file stream open and ready.

How do I seek a single byte in the stream and change it so that change is reflected on the file?

+5  A: 
FILE* fileHandle = fopen("filename", "r+b"); // r+ if you need char mode
fseek(fileHandle, position_of_byte, SEEK_SET);
fwrite("R" /* the value to replace with */, 1, 1, fileHandle);
Mehrdad Afshari
"rw" truncates the file. You need "rb".
Alex B
sizeof(char) == 1, by definition.
dirkgently
Everybody is right :) Long time no C.
Mehrdad Afshari
@Greg, on POSIX systems (Linux included) "r+" will do and "b" is ignored. Sadly, on Windows you have to include "b" for binary mode.
Alex B
+3  A: 
#include "stdio.h"

int main(void)
{
    FILE* f = fopen("so-data.dat", "r+b"); // Error checking omitted
    fseek(f, 5, SEEK_SET);
    fwrite("x", 1, 1, f);
    fclose(f);
}
RichieHindle
A (f != NULL) is required. fclose(NULL) invokes UB.
dirkgently
fwrite("x", 1, 1, f);Doesn't this write the first byte of the address of the string "x"?
Blank Xavier
No, it doesn't - ignore me :-)
Blank Xavier
@Blank, the first arg is a *pointer* to data.
Mehrdad Afshari
Doesn't the r+ permission disallow writing?
cletus
@cletus: Then what "r" is expected to do? "r+" is read/write.
Mehrdad Afshari
Note that jumping to computed locations in a *text* mode file is implementation defined. For a platform where text and binary modes are different (i.e., almost everything except Unix), you'll need to handle the fact that newlines can be multiple bytes (or otherwise funny). Whether this matters to Yuval A I don't know.
Lars Wirzenius
@liw.fi: see also http://stackoverflow.com/questions/229924/difference-between-files-writen-in-binary-and-text-mode ; I'd recommend to always open files in binary mode by default so you can be sure that what you see is what you get
Christoph
@liw.fi, @Christoph: Good point; changed to binary.
RichieHindle
+3  A: 
#include <stdio.h> /* standard header, use the angle brackets */

int main(void)
{
    char somechar = 'x'; /* one-byte data */
    FILE* fp = fopen("so-data.txt", "r+");
    if (fp) {
      fseek(fp, 5, SEEK_SET);
      fwrite(&somechar, 1, 1, fp);
      fclose(fp);
    }
    return 0; /* if you are on non-C99 systems */
}
dirkgently