Usage of fmemopen
Asked Answered
A

1

1

I don't understand an example of fmemopen from APUE

#include <stdio.h>
#include <string.h>

#define BSZ 48

int
main()
{
    FILE *fp;
    char buf[BSZ];

    memset(buf, 'a', BSZ-2);
    buf[BSZ-2] = '\0';
    buf[BSZ-1] = 'X';
    if ((fp = fmemopen(buf, BSZ, "w+")) == NULL)  //"w+" truncate the file by setting the first byte to null byte
        printf("fmemopen failed\n");
    printf("initial buffer contents: %s\n", buf); //print nothing cause the first byte is null byte.
    fprintf(fp, "hello, world"); //write format string to the stream, so the buffer should change and be rewritten.
    printf("before flush: %s\n", buf); //should print "hello, world". Why not?
    fflush(fp);
    printf("after fflush: %s\n", buf);
    printf("len of string in buf = %ld\n", (long)strlen(buf));

    memset(buf, 'b', BSZ-2);
    buf[BSZ-2] = '\0';
    buf[BSZ-1] = 'X';
    fprintf(fp, "hello, world");
    fseek(fp, 0, SEEK_SET);
    printf("after  fseek: %s\n", buf);
    printf("len of string in buf = %ld\n", (long)strlen(buf));

    memset(buf, 'c', BSZ-2);
    buf[BSZ-2] = '\0';
    buf[BSZ-1] = 'X';
    fprintf(fp, "hello, world");
    fclose(fp);
    printf("after fclose: %s\n", buf);
    printf("len of string in buf = %ld\n", (long)strlen(buf));

    return(0);
}

I use Clion to debug and when it finishes fprintf(fp, "hello, world"); and comes to printf("before flush: %s\n", buf);, I see the content of char array buf does not change and print nothing. Why!?

A debug screenshot for better description:

enter image description here

Also, quoted from the book:

Third, a null byte is written at the current position in the stream whenever we increase the amount of data in the stream’s buffer and call fclose, fflush, fseek, fseeko, or fsetpos.

What does this mean?


Update:

From the book and it seems that buffer is unchanged until stream is flushed is the expected result.

enter image description here

Access answered 7/3, 2019 at 2:34 Comment(3)
I get before flush: hello, world.Mascon
I get that on Mac, but it's empty on Linux. I guess different C libraries do it differently.Mascon
@Mascon I got _fmemopen symbol not found on Mac... Linker error.Access
R
-2

change the allocated buf array in the stack

char buf[BSZ];

to this

char* buf = new(std::nothrow) chr[BSZ];

and freed buf after close the stream

delete[] buf

and test again.

Reft answered 17/2, 2020 at 11:45 Comment(3)
This fails with various syntax errors: C ≠ C++. Besides, the original code is fine and this is unrelated to the question.Mythology
related to the question, Because buf must be allocated in HEAP , not in STACKReft
No, that is incorrect. There’s no reason why the memory couldn’t be stack-allocated.Mythology

© 2022 - 2024 — McMap. All rights reserved.