Question

I have small problem with rewriting first 2,5KB of file. My code should read 2KB and 512 bytes to dynamically allocated memory and then rewrite specific bytes of much larger file.

f = fopen(argv[2], "rb");
if(f==NULL)
    printf("File doesn't exist!");
fseek(f, 0, SEEK_SET);
data = calloc(2*1024+512, 1);
fread(data, 1, 2*1024+512, f);
fclose(f);

f = fopen(argv[1], "ab");
if(f==NULL)
    printf("File doesn't exist!");
fseek(f, 0, SEEK_SET);
fwrite(data, 1, 446, f);
fseek(f, 512, SEEK_SET);
fwrite(((char*)data)+512, 1, 2*1024, f);
fclose(f);

When I try to use wb mode, it erases contents of second file. When I use ab mode and seek to the start of file, previous content is appended on the end.

Is there any way (using standard C libraries) to rewrite file contents without appending and copying remaining content of written file? Please help.

Was it helpful?

Solution 2

The "rb" mode opens the file positioned at the start; the initial fseek() is redundant.

The second open with "ab" opens the file for writing in append mode. All writes will occur at the end of the file, regardless of what fseek() operations you do beforehand.

You could sensibly use mode "rb+" to open the file once for both reading and writing:

if ((f = fopen(argv[2], "rb+")) != 0)
{
    char *data = calloc(2*1024+512, 1);   // Missing error check
    fread(data, 1, 2*1024+512, f);        // Missing error check
    // Modify data?
    fseek(f, 0, SEEK_SET);
    fwrite(data, 1, 446, f);
    fseek(f, 512, SEEK_SET);
    fwrite(((char*)data)+512, 1, 2*1024, f);
    fclose(f);
}

The code should check that the calloc() succeeds before using data; it should also error check the fread() to be sure it got the expected data. Presumably, something in the middle will modify the data read from the file.


ISO/IEC 9899:2011 (the current C standard) has this to say about the modes for fopen() — and the previous standards said much the same except for the x flag, which is new in C11:

§7.21.5.3 The fopen function

¶3 The argument mode points to a string. If the string is one of the following, the file is open in the indicated mode. Otherwise, the behavior is undefined.271)

  • r open text file for reading
  • w truncate to zero length or create text file for writing
  • wx create text file for writing
  • a append; open or create text file for writing at end-of-file
  • rb open binary file for reading
  • wb truncate to zero length or create binary file for writing
  • wbx create binary file for writing
  • ab append; open or create binary file for writing at end-of-file
  • r+ open text file for update (reading and writing)
  • w+ truncate to zero length or create text file for update
  • w+x create text file for update
  • a+ append; open or create text file for update, writing at end-of-file
  • r+b or rb+ open binary file for update (reading and writing)
  • w+b or wb+ truncate to zero length or create binary file for update
  • w+bx or wb+x create binary file for update
  • a+b or ab+ append; open or create binary file for update, writing at end-of-file

271) If the string begins with one of the above sequences, the implementation might choose to ignore the remaining characters, or it might use them to select different kinds of a file (some of which might not conform to the properties in §7.21.2).

OTHER TIPS

You want ab+. The + signifies update mode. If the file exists, it will simply be opened and the contents not changed. wb by itself will simply erase the original file and create a new one.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top