Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我可以用malloc和隐式cast替换对open_memstream的调用吗?_C_Windows_Stream_Malloc - Fatal编程技术网

我可以用malloc和隐式cast替换对open_memstream的调用吗?

我可以用malloc和隐式cast替换对open_memstream的调用吗?,c,windows,stream,malloc,C,Windows,Stream,Malloc,全部, 我有一个打印到流的程序。我需要在内存中缓冲这个流,然后根据需要将每一行打印到实际文件中 由于fprintf()函数调用必须有一个文件*指针,所以我需要在内存中有指针寻址空间。我使用了open\u memstream()函数,但windows不支持此功能 由于malloc()返回一个void*指针,该指针可以根据需要神奇地强制转换到所需的指针,我可以将其用作我的文件*指针吗?如果是,有哪些注意事项?我需要注意空间不够吗 更新: 在找到open_memstream()的源代码后(这比应该的要

全部,

我有一个打印到流的程序。我需要在内存中缓冲这个流,然后根据需要将每一行打印到实际文件中

由于
fprintf()
函数调用必须有一个
文件*
指针,所以我需要在内存中有指针寻址空间。我使用了
open\u memstream()
函数,但windows不支持此功能

由于
malloc()
返回一个
void*
指针,该指针可以根据需要神奇地强制转换到所需的指针,我可以将其用作我的
文件*
指针吗?如果是,有哪些注意事项?我需要注意空间不够吗

更新:

在找到
open_memstream()
的源代码后(这比应该的要难),看起来他们正在对malloc的空间进行文件流

既然是这样,而且我已经得到了它们的源代码,如果我不能得到一个工作版本来为windows与mingw交叉编译,我将使用se

No.
malloc()
只提供一块(可能未初始化)内存。没有“神奇”的演员阵容;当您执行
int*buf=malloc(10*sizeof(int);
时,实际上是将
buf
指向10个未初始化的整数

与文件对应的是
FILE*f=malloc(10*sizeof(FILE));
它指向10个未初始化的文件结构,这没有任何意义。此外,如果幸运的话,写入未初始化的文件可能会导致崩溃


如果你告诉我们你的目标是什么平台以及你真正想要实现什么,那么帮助就更容易了。在POSIX上,你可以使用
shm_open()
获取指向“共享内存”和
fdopen()的文件描述符
将文件描述符转换为
文件*
。是的,它可能会耗尽空间。

对于我之后的人,希望吧!有一个解决方案。正如我在问题中提到的,我使用的是windows不支持的
open_memstream()

由于我有一个
文件*
指针(不能更改为
字符*
),我需要将其重定向到内存,直到稍后。由于我在内存中处理一个文件,我查看了
mmap()
。它轻松地解决了问题,但同样,它只是linux

但是,windows包含了
mmap()
的一个推论,称为
MapViewOfFile()
。通过
#ifdef
的魔力,我使用了任何必要的工具:

#ifdef WIN32
#include <windows.h>
#else
#include <sys/mman.h>
#endif
现在我有了更多的
#ifdef
代码来确定需要使用哪个内存映射代码集。请注意这两个版本之间映射空间的差异。Windows映射16384字节和linux映射4096字节。这是因为较小的值会在Windows上出错,如中所述

当数据被发送到
yyout
流时,会发生一系列的工作方法被调用。它用一个以null结尾的字符结束流,刷新它,然后倒带它。然后指向内存空间的指针通过一个函数指针,以及要打印到的正确流

void flushData(void) {
    /* write out data in the stream and reset */ 
    while (currFields < headerFields) { fprintf(yyout, ",\"\""); currFields++; } 
    currFields = 0;
    fprintf(yyout, "%c%c%c", 13, 10, '\0');
    fflush(yyout);
    rewind(yyout);
    if (faqLine == 1) {
        faqLine = 0; /* don't print faq's to the data file */
    }
    else {
        (*printString)(outfile, bp);
        fflush(outfile);
    }
    fflush(yyout);
    rewind(yyout);
}
所有这一切的最终结果是,我有一个流到内存空间,就像
open_memstream()
,还有一个char指针,如果需要,我可以用来遍历内存空间。它是跨平台的,而且(似乎)功能齐全


如果有人想了解更多详细信息或了解我应该解决的问题,请添加评论。

你让它工作了吗?,很好!在研究同一问题时,我还发现了这个麻省理工学院授权的库,它看起来基本上做了相同的解决方案,尽管它试图跨平台,并检测用户环境提供了什么完成后,是否调用
UnmapViewOfFile
或除
fclose
之外的任何其他清理功能?
#ifdef WIN32
    HANDLE fm;
    HANDLE h = (HANDLE) _get_osfhandle (fd);

    fm = CreateFileMapping(
             h,
             NULL,
             PAGE_READWRITE|SEC_RESERVE,
             0,
             16384,
             NULL);
    if (fm == NULL) { 
            fprintf (stderr, "%s: Couldn't access memory space! %s\n", argv[0],  strerror (GetLastError()));
            exit(GetLastError());
    }
    bp = (char*)MapViewOfFile(
              fm,
              FILE_MAP_ALL_ACCESS,
              0,
              0,
              0);
    if (bp == NULL) { 
            fprintf (stderr, "%s: Couldn't fill memory space! %s\n", argv[0],  strerror (GetLastError()));
            exit(GetLastError());
    }
#else
    bp = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_FILE|MAP_PRIVATE, fd, 0);
    if (bp == MAP_FAILED) {
            fprintf (stderr, "%s: Couldn't access memory space! %s\n", argv[0], FileName, strerror (errno));
            exit(errno);
    }
#endif
void flushData(void) {
    /* write out data in the stream and reset */ 
    while (currFields < headerFields) { fprintf(yyout, ",\"\""); currFields++; } 
    currFields = 0;
    fprintf(yyout, "%c%c%c", 13, 10, '\0');
    fflush(yyout);
    rewind(yyout);
    if (faqLine == 1) {
        faqLine = 0; /* don't print faq's to the data file */
    }
    else {
        (*printString)(outfile, bp);
        fflush(outfile);
    }
    fflush(yyout);
    rewind(yyout);
}
int printAnsi( FILE *outstream, char *string) {
    /* loop over the chars in string and print them to the outputstream as ansi */
    char * ps = string;
    while (*ps != '\0') {
        fprintf(outstream, "%c", *ps);
        ps++;
    }
    return 0;
}