C#具有能够使用MemoryStream对象写入内存流的简洁功能。
我正在使用FILE *指针从C中寻找类似的功能。
我希望能够sprintf(),但是在我正在写入的缓冲区中添加了C记住“我在哪里”的功能。
答案 0 :(得分:5)
如果您使用的是GNU C库,则可以使用fmemopen()。其他环境可能还有其他非可移植扩展,但没有使用FILE *的可移植方式。
但是,如果你不坚持实际使用FILE *,你也可以包装snprintf。例如,glib(注意:与GNU C库不同,并且可移植)具有g_string_append_printf,可以满足您的需求。
答案 1 :(得分:3)
还有一个丑陋的黑客可以使用普通的ISO-C:您可以使用fopen()
打开一个空文件(* /dev/null
在* nix上,NUL
在Windows上)并设置数组作为文件的缓冲区通过
setvbuf(file, buffer, _IOFBF, buffer_size)
只要代码中的任何地方都没有调用fflush()
,这应该可以正常工作。此外,程序员必须明确地处理字符串分隔符。
我并不认为有必要这样做:当snprintf()
返回写入的字符数时,跟踪缓冲区的位置是微不足道的。
甚至可以编写一个函数来在溢出时自动调整缓冲区的大小:bufprintf.c
该函数的原型是
int bufprintf(char **buffer, size_t *size, size_t *offset,
const char *format, ...);
示例程序可能如下所示:
#include <stdio.h>
extern int bufprintf(char **buffer, size_t *size, size_t *offset,
const char *format, ...);
int main(void)
{
size_t size = 0; // must be set!
size_t offset;
char * buffer;
for(int i = 0; i < 100; ++i)
bufprintf(&buffer, &size, &offset, "we rock %i\n", i);
puts(buffer);
printf("size:\t%u\noffset:\t%u\n", (unsigned)size, (unsigned)offset);
}
答案 2 :(得分:2)
sprintf返回打印到字符串中的字符数。您可以使用该值来递增缓冲区的指针。
buffer += sprintf(buffer, "%d", i);
确保保留原始指针的副本,因为这是在将缓冲区传递到其他位置时将使用的内容。
答案 3 :(得分:0)
为什么不使用mmap?您可以将文件映射到内存并使用FILE *指针。
更新:它不起作用。遗憾。
答案 4 :(得分:0)
MemoryStream
不是语言C#的一个功能。它只是BCL中的一个类。你可以在C#中自己编写。
所以它在C中 - 您可以编写一些功能类似于fopen
,fprintf
,fwrite
,fclose
等的功能,但是给他们一些名字,如mopen
,mwrite
等(大概)并写下来,使它们在内存缓冲区上运行。
答案 5 :(得分:0)
如何手动管理指针呢?我前面没有编译器,但希望下面的代码可以解决这个问题:
char huge_buffer[REALLY_BIG_SIZE];
char *write_pos = huge_buffer;
//...
void fprintf_to_mem(char **mem_ptr, const char *fmt, ...)
{
va_list args;
int num_written;
va_start(args, mem_ptr);
num_written = vsprintf(*write_pos, fmt, args);
*write_pos += num_written;
va_end(args);
}
//...
fprintf_to_mem(&write_pos, "Testing %d %d %d", 1, 2, 3);
fprintf_to_mem(&write_pos, "Hello world!\r\n");
我希望输出“Testing 1 2 3Hello world!\ r \ n”到huge_buffer。