Register
Handmade Hero»Forums»Code»stdio.h file I/O question about: "ab+" vs "wb+" -> "rb+"
76 posts
stdio.h file I/O question about: "ab+" vs "wb+" -> "rb+"
3 weeks ago Edited by C_Worm on Sept. 3, 2020, 7:11 p.m. Reason: Initial post
Hey im making a tilemap editor and are working on saving and loading tilemaps. Write now im only writing what texture fragment the selected tile has into a file.

Then I read that info into a stand alone SDL_Rect, just for testing.

im using stdio.h file I/O

So im wondering why the "ab+" doesn't update the buffer that read from the file data.


but it works when i open the file TWICE using different modes "wb+" and then "rb+"


Using "ab+": This sets the rect_info once and doesn't update it as the values change.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
            if(KeyPressed[mouse_L])
            {
                engine->saveTileMap = true;
                
                FILE *f_savedTileMap = fopen("SavedMaps\\newTileMap.txt", "ab+");
                
                rewind(f_savedTileMap);
                size_t nWritten = fwrite(&world->tile[0].textureFragment, sizeof(SDL_Rect), 1, f_savedTileMap);
                
                SDL_Rect readData = {};
                
                rewind(f_savedTileMap);
                fread(&readData, sizeof(SDL_Rect), 1, f_savedTileMap);
                
                fclose(f_savedTileMap);
                
                
                printf("Elements written: %zu\n", nWritten);
                printf("read Rect: {%d, %d, %d, %d}\n", readData.x, readData.y, readData.w, readData.h);
                
                engine->saveTileMap = false;
                
                
            }
            




Using "wb+" and then "rb+" and this works.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    if(KeyPressed[mouse_L])
    {
        engine->saveTileMap = true;
        
        FILE *f_savedTileMap = fopen("SavedMaps\\newTileMap.txt", "wb+");
        
        size_t nWritten = fwrite(&world->tile[0].textureFragment, sizeof(SDL_Rect), 1, f_savedTileMap);
        
        printf("Elements written: %zu\n", nWritten);
        fclose(f_savedTileMap);
        
        SDL_Rect readData = {};
        f_savedTileMap = fopen("SavedMaps\\newTileMap.txt", "rb+");
        fread(&readData, sizeof(SDL_Rect), 1, f_savedTileMap);
        
        fclose(f_savedTileMap);
        
        
        
        printf("read Rect: {%d, %d, %d, %d}\n", readData.x, readData.y, readData.w, readData.h);
        
        engine->saveTileMap = false;
    }
    




Im wondring if it would be possible to just open the file once and do both read and write operations on it, and i guess that should be done using "ab+"?


Simon Anciaux
882 posts
stdio.h file I/O question about: "ab+" vs "wb+" -> "rb+"
3 weeks ago Edited by Simon Anciaux on Sept. 3, 2020, 7:35 p.m.
If you use a it means that every write operation will write at the end of the file, even if you try to move the cursor using fseek. It means the file gets larger and larger, check the size of your file after trying to update it several times to confirm this.

Here is the documentation of fopen.

Since you have a function called rewind, I suppose you try moving the write position before writing which will not work.

I believe the mode you want is w+. Pay attention to this paragraph in the doc:
For files open for update (those which include a "+" sign), on which both input and output operations are allowed, the stream shall be flushed (fflush) or repositioned (fseek, fsetpos, rewind) before a reading operation that follows a writing operation. The stream shall be repositioned (fseek, fsetpos, rewind) before a writing operation that follows a reading operation (whenever that operation did not reach the end-of-file).

76 posts
stdio.h file I/O question about: "ab+" vs "wb+" -> "rb+"
3 weeks ago
okay, rewind() is a part of stdio.h, i didn't write that.

i found the reopen() function now, which can be used to change access mode :)

, thanks! :)