C 创建导致字符串的文件*流
我正在寻找一种将C 创建导致字符串的文件*流,c,string,file,stream,printf,C,String,File,Stream,Printf,我正在寻找一种将文件*传递给某个函数的方法,以便该函数可以使用fprintf对其进行写入。如果我希望输出出现在磁盘上的实际文件中,比如说,这很容易。但我希望的是将所有输出作为字符串(char*)获取。我喜欢的API类型是: /** Create a FILE object that will direct writes into an in-memory buffer. */ FILE *open_string_buffer(void); /** Get the combined string
文件*
传递给某个函数的方法,以便该函数可以使用fprintf
对其进行写入。如果我希望输出出现在磁盘上的实际文件中,比如说,这很容易。但我希望的是将所有输出作为字符串(char*
)获取。我喜欢的API类型是:
/** Create a FILE object that will direct writes into an in-memory buffer. */
FILE *open_string_buffer(void);
/** Get the combined string contents of a FILE created with open_string_buffer
(result will be allocated using malloc). */
char *get_string_buffer(FILE *buf);
/* Sample usage. */
FILE *buf;
buf = open_string_buffer();
do_some_stuff(buf); /* do_some_stuff will use fprintf to write to buf */
char *str = get_string_buffer(buf);
fclose(buf);
free(str);
glibc的glibc头似乎表示可以使用钩子函数设置文件,以执行实际的读写操作。在我的例子中,我想我希望write钩子将字符串的一个副本附加到一个链接列表中,并且有一个get\u string\u buffer
函数,它计算出列表的总长度,为列表分配内存,然后将每个项复制到正确的位置
我的目标是可以传递给函数的东西,比如do\u some\u stuff
,而该函数不需要知道除此之外的任何东西,它有一个文件*
可以写入
有这样的实现吗?这似乎是一件有用且对C友好的事情——假设我对
文件
可扩展性的看法是正确的。我不确定是否可以不可移植地扩展文件
对象,但如果您正在寻找对POSIX更友好的东西,可以使用管道
和fdopen
它与从缓冲区返回字节的文件*
并不完全相同,但它肯定是一个具有编程确定内容的文件*
int fd[2];
FILE *in_pipe;
if (pipe(fd))
{
/* TODO: handle error */
}
in_pipe = fdopen(fd[0], "r");
if (!in_pipe)
{
/* TODO: handle error */
}
从那里,您需要使用write()
将缓冲区写入fd[1]
。不过,请小心此步骤,因为如果管道的缓冲区已满(即,需要有人读取另一端),则write()
可能会阻塞,如果进程在写入时收到信号,则可能会得到EINTR
。还要注意SIGPIPE
,当另一端关闭管道时会发生这种情况。为了便于使用,您可能希望在单独的线程中执行缓冲区的写入
,以避免阻塞,并确保处理SIGPIPE
当然,这不会创建一个可查找的
文件*
..如果可移植性对您来说并不重要,您可以查看并查看。它们是GNU扩展,因此仅在glibc系统上可用。虽然看起来它们是POSIX.1-2008(和)的一部分。但我不确定我是否理解您为什么要处理文件*。你不能简单地写一个文件,然后用字符串加载它吗
char *get_file_in_buf(char *filename) {
char *buffer;
... get file size with fseek or fstat ...
... allocate buffer ...
... read buffer from file ...
return buffer;
}
如果您只想将格式化文本“写入”到字符串中,另一个选项可以是使用snprintf()
处理可扩展缓冲区(有关如何处理此问题的建议,请参阅此问题的答案:)
相反,如果您想创建一个类型,该类型可以透明地传递给任何使用
文件*
的函数,使它们作用于字符串缓冲区,那么这是一个更复杂的问题…open\u memstream正是我想要的。我不确定它是否使用了链表方法,但我不会向它写入大量数据,所以这无关紧要。有很好的理由需要这样一个文件*
:有许多库只提供基于文件*
)的I/O,并且坚持读取文件,而数据可能已经存在于内存中。因此,我们希望能够传递内存缓冲区,而不是仅仅针对这些库将其写入文件。不幸的是,这些库很少(如果有的话)提供其依赖于文件的API的替代方案。