Creating a FILE * stream that results in a string

后端 未结 3 1305
星月不相逢
星月不相逢 2020-12-06 13:40

I\'m looking for a way to pass in a FILE * to some function so that the function can write to it with fprintf. This is easy if I want the output t

相关标签:
3条回答
  • 2020-12-06 14:17

    If portability is not important for you, you can take a look on fmemopen and open_memstream. They are GNU extensions, hence only available on glibc systems. Although it looks like they are part of POSIX.1-2008 (fmemopen and open_memstream).

    0 讨论(0)
  • 2020-12-06 14:22

    I'm not sure I understand why you want to mess up with FILE *. Couldn't you simply write to a file and then load it in string?

     char *get_file_in_buf(char *filename) {
       char *buffer;
       ... get file size with fseek or fstat ...
       ... allocate buffer ...
       ... read buffer from file ...
       return buffer;
     }
    

    If you only want to "write" formatted text into a string, another option could be to handle an extensible buffer using snprintf() (see the answers to this SO question for a suggestion on how to handle this: Resuming [vf]?nprintf after reaching the limit).

    If, instead, you want to create a type that can be passed transparently to any function taking a FILE * to make them act on string buffers, it's a much more complex matter ...

    0 讨论(0)
  • 2020-12-06 14:24

    I'm not sure if it's possible to non-portably extend FILE objects, but if you are looking for something a little bit more POSIX friendly, you can use pipe and fdopen.

    It's not exactly the same as having a FILE* that returns bytes from a buffer, but it certainly is a FILE* with programmatically determined contents.

    int fd[2];
    FILE *in_pipe;
    
    if (pipe(fd))
    {
       /* TODO: handle error */
    }
    
    in_pipe = fdopen(fd[0], "r");
    if (!in_pipe)
    {
       /* TODO: handle error */
    }
    

    From there you will want to write your buffer into fd[1] using write(). Careful with this step, though, because write() may block if the pipe's buffer is full (i.e. someone needs to read the other end), and you might get EINTR if your process gets a signal while writing. Also watch out for SIGPIPE, which happens when the other end closes the pipe. Maybe for your use you might want to do the write of the buffer in a separate thread to avoid blocking and make sure you handle SIGPIPE.

    Of course, this won't create a seekable FILE*...

    0 讨论(0)
提交回复
热议问题