ungetc after a fwrite, fseek and fwrite fails
02:48 19 Dec 2025

After reading a draft of the c23 standard (n3220), I was trying to gain an understanding of ungetc by writing a simple example.

In This Example I:

  • fopen a file named file.txt for updating, either created or truncated to zero length
  • fwrite the message "hello-world" to the stream f
  • fseek to 4 bytes from the start of the stream f
  • fwrite the text "erm" to the stream f
  • call ungetc to push the character 'z' to the stream f

This example is shown below

//main4.c
#include 

#define EXIT_FAILURE 1

void output_errors(FILE* f){
    printf("ferror=%d, feof=%d\n", ferror(f), feof(f));
}

int main(){
    #define MSG "hello-world"
    #define ERM "erm"
    FILE* f;
    const long offset = 4;  //o
    const char c = 'z';
    const char* name = "file.txt";
    const char* mode = "wb+";
    f = fopen(name, mode);
    if (!f){
        puts("File Wasnt Created");
        return EXIT_FAILURE;
    }
    {
        size_t elems;
        elems = fwrite(MSG, sizeof *MSG, sizeof MSG - 1, f);
        if (elems < sizeof MSG - 1){
            printf("MSG Write: %d Elements Written. Expected %d\n", 
                (int)elems, (int)sizeof MSG - 1);
            return EXIT_FAILURE;
        }
    }
    if (fseek(f, offset, SEEK_SET)){
        puts("first seeking request could not be satisfied");
        return EXIT_FAILURE;
    }
    {
        size_t elems;
        elems = fwrite(ERM, sizeof *ERM, sizeof ERM - 1, f);
        if (elems < sizeof ERM - 1){
            printf("ERM Write: %d Elements Written. Expected %d\n", 
                (int)elems, (int)sizeof MSG - 1);
            return EXIT_FAILURE;
        }
    }
    output_errors(f);
    if (ungetc(c, f) == EOF){
        output_errors(f);
        puts("ungetting c1 failed");
        return EXIT_FAILURE;
    }
}

The commands to compile and execute this file used were:

gcc main4.c -Werror -Wextra -Wpedantic -Wconversion -Wshadow -g -std=c23
a.exe

I expected only the following output to stdout, indicating no errors occurred:

ferror=0, feof=0

Instead, I received the following error message

ferror=0, feof=0
ferror=0, feof=0
ungetting c1 failed

Could someone please explain why i am receiving this error?

A pushback of one character is guaranteed.

c stdio ungetc