21

我有一个 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);
}
4

5 回答 5

26

标准 C 没有提供这样的功能,但 POSIX 定义了fmemopen()完全符合您要求的功能。

于 2012-07-08T08:29:40.700 回答
8

不幸的是,C 的标准库不提供这个功能。但有几种方法可以绕过它:

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

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

  • 正如@KeithThompson 指出的那样,fmemopen完全符合您的要求,因此如果您有 POSIX,请使用它。在任何其他平台上,(除非您可以找到等效平台),您将需要一个临时文件。

于 2012-07-08T08:27:00.737 回答
3

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

可能还有其他方法,例如创建内存映射文件,但我一直在寻找无需大量工作和研究即可工作的东西。

编辑:当然,您可以将问题更改为“我如何找到一个不错的临时文件名”。然后您可以将数据写入文件,然后将其读回:-)

于 2012-07-08T08:24:12.427 回答
2
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

....  .....
于 2012-07-08T08:44:27.683 回答
2

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

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.
}

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

现在,您可以简单地向您的解析函数发送一个句柄。该函数不关心数据来自哪里,它甚至可以从网络中读取数据!

于 2012-07-08T13:02:27.660 回答