使用类似文件的C字符串*

我有一个C函数,从FILE*读取字符流。

在这种情况下,如何从字符串创建FILE*

编辑:

我认为我的原帖可能会产生误导。 我想从文字字符串值创建一个FILE* ,这样生成的FILE*就会像某个文件某处包含字符串而不实际创建文件一样。

以下是我想做的事情:

 void parse(FILE* f, Element* result); int main(int argc, char** argv){ FILE* f = mysteryFunc("hello world!"); Element result; parse(f,&result); } 

标准C不提供这样的function,但POSIX定义了fmemopen()函数,它完全符合您的要求。

不幸的是,C的标准库不提供此function; 但有几种方法可以解决它:

  • 创建一个临时文件,将字符串写入其中,然后打开它进行读取。 如果您有POSIX, gettempnam将为您选择一个唯一的名称

  • 另一个选项(仅适用于POSIX)是fork一个新进程,其作用是将字符串write管道,而另一端fdopen为您的函数获取FILE*

  • 正如@KeithThompson指出的那样, fmemopen确实是你想要的,所以如果你有POSIX,请使用它。 在任何其他平台上,(除非你能找到平台等价的),你需要一个临时文件。

上次我遇到这种问题时,我实际创建了一个管道,启动了一个线程,并使用该线程将数据写入管道……但是你必须查看操作系统调用。

可能还有其他方法,比如创建一个内存映射文件,但我正在寻找一些没有大量工作和研究工作的东西。

编辑:当然,您可以将问题更改为“我如何找到一个漂亮的临时文件名”。 然后你可以将数据写入文件,并在以下内容中读取:-)

 pid_t pid; int pipeIDs[2]; if (pipe (pipeIDs)) { fprintf (stderr, "ERROR, cannot create pipe.\n"); return EXIT_FAILURE; } pid = fork (); if (pid == (pid_t) 0) { /* Write to PIPE in this THREAD */ FILE * file = fdopen( pipe[1], 'w'); fprintf( file, "Hello world"); return EXIT_SUCCESS; } else if (pid < (pid_t) 0) { fprintf (stderr, "ERROR, cannot create thread.\n"); return EXIT_FAILURE; } FILE* myFile = fdopen(pipe[0], 'r'); // DONE! You can read the string from myFile .... ..... 

也许您可以稍微更改代码以接收自定义句柄。

 void parse(my_handle *h, Element *result) { // read from handle and process // call h->read instead of fread } 

并定义这样的句柄:

 struct my_handle { // wrapper for fread or something int (*read)(struct my_handle *h, char *buffer, int readsize); // maybe some more methods you need }; 

实现你的FILE *包装器

 struct my_file_handle { struct my_handle base; FILE *fp; }; int read_from_file(struct my_handle *h, char *buffer, int readsize) { return fread(buffer, 1, readsize, ((my_file_handle*)h)->fp); } // function to init the FILE* wrapper void init_my_file_handle(struct my_file_handle *h, FILE *fp) { h->base.read = read_from_file; h->fp = fp; } 

现在,实现你的字符串阅读器

 struct my_string_handle { struct my_handle base; // string buffer, size, and current position const char *buffer; int size; int position; }; // string reader int read_from_string(struct my_handle *h, char *buffer, int readsize) { // implement it yourself. It's easy. } // create string reader handle void init_my_string_handle(struct my_string_handle *h, const char *str, int strsize) { // i think you know how to init it now. } 

//////////////////////////////////////////////////

现在,您只需向解析函数发送一个句柄即可。 该function不关心数据来自何处,甚至可以从网络读取数据!