侧边栏壁纸
博主头像
noerror

虚灵不寐,众理具而万事出。

  • 累计撰写 238 篇文章
  • 累计创建 9 个标签
  • 累计收到 2 条评论
标签搜索

目 录CONTENT

文章目录

fmemopen函数用法详解

noerror
2022-10-04 / 0 评论 / 0 点赞 / 35 阅读 / 1,461 字 / 正在检测是否收录...

fmemopen函数用法详解

fmemopen函数简介

  • 头文件包含
#include <stdio.h>
  • 函数定义
FILE *fmemopen(void *buf , size_t size , const char * mode );

fmemopen函数常见使用错误

  • 编译错误
    warning: implicit declaration of function ‘fmemopen’ [-Wimplicit-function-declaration]
    解决办法:包含头文件
#include <stdio.h>

fmemopen函数详细描述

fmemopen ()函数打开一个允许mode 指定的访问的流,该流允许在buf 指向的字符串或内存缓冲区上执行I/O
mode参数指定流上I/O的语义,它是以下内容之一:

  • r流打开以供读取。
  • w流已打开以进行写入。
  • a追加;打开用于写入的流,初始缓冲区位置设置为第一个空字节。
  • r+打开流进行读写。
  • w+打开流进行读写。缓冲区内容被截断(即(aq\e0(aq放在缓冲区的第一个字节中)。
  • a+追加;打开流进行读写,初始缓冲区位置设置为第一个空字节。

流保持当前位置的概念,即执行下一个I/O操作的位置。当前位置由I/O操作隐式更新。它可以使用fseek (3)显式更新,并在除追加之外的所有模式下使用ftell (3)确定,初始位置被设置为缓冲区的开始。在追加模式下,如果在缓冲区中没有找到空字节,那么初始位置是size+1
如果将buf指定为NULL,那么fmemopen ()将分配一个size字节的缓冲区。这对于希望将数据写入临时缓冲区,然后再将其读回的应用程序非常有用。初始位置被设置为缓冲区的开始。当流关闭时,缓冲区将自动释放。请注意,调用方无法获得指向此调用所分配的临时缓冲区的指针(但请参见open_memstream (3))
如果buf不是NULL,那么它应该指向调用方分配的至少有len字节的缓冲区。
当已打开用于写入的流被刷新( fflush (3))或关闭( fclose (3))时,如果有空间,则在缓冲区的末尾写入一个空字节。调用方应该确保缓冲区中有一个额外的字节可用(并且size对该字节进行计数),以允许这样做。
在为读取而打开的流中,缓冲区中的空字节((aq\e0(aq)不会导致读取操作返回文件结束指示。只有当当前缓冲区位置将size字节提前超过缓冲区开始时,从缓冲区读取才会指示文件结束。
写操作要么发生在当前位置(对于追加模式以外的模式),要么发生在流的当前大小(对于追加模式)。
试图向缓冲区写入超过size字节将导致错误。默认情况下,只有在刷新stdio缓冲区时,这样的错误才会(由于没有数据)可见。使用以下调用禁用缓冲对于在输出操作时检测错误可能很有用:
setbuf(流,空);

fmemopen函数返回值

成功完成后,fmemopen ()返回一个FILE指针。否则,返回NULL,并设置errno以指示错误。

fmemopen函数其他说明

没有与此函数返回的文件流相关联的文件描述符(即,如果在返回的流上调用fileno (3)将返回错误)。
在2.22版本中,删除了二进制模式(见下文),修复了fmemopen ()实现中的许多长期存在的错误,并为该接口创建了一个新的版本符号。Binary mode从2.9到2.21版本,fmemopen ()的glibc实现支持“二进制”模式,通过指定字母(aqb(aq)作为mode 中的第二个字符来启用,在此模式下,写入不隐式添加终止空字节,fseek (3) SEEK_END 相对于缓冲区的结尾(即,由size参数指定的值),而不是当前字符串长度。
一个API bug影响了二进制模式的实现:要指定二进制模式,(aqb(aq)必须是mode 中的second字符,因此,例如,“wb+”具有预期的效果,而“w+b”则没有,这与fopen (3)对mode的处理不一致
在glibc2.22中删除了二进制模式;在mode中指定的a(aqb(aq)不起作用。

fmemopen函数使用举例

下面的程序使用fmemopen ()打开输入缓冲区,使用open_memstream (3)打开动态大小的输出缓冲区。程序扫描其输入字符串(取自程序的第一个命令行参数),读取整数,并将这些整数的平方写入输出缓冲区。该程序产生的输出示例如下:

" ./a.out \(aq1 23 43\(aq"
size=11; ptr=1 529 1849

Program source&

#define _GNU_SOURCE
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#define handle_error(msg) \e
   do { perror(msg); exit(EXIT_FAILURE); } while (0)

int
main(int argc, char *argv[])
{
   FILE *out, *in;
   int v, s;
   size_t size;
   char *ptr;

   if (argc != 2) {
       fprintf(stderr, "Usage: %s \(aq<num>...\(aq\en", argv[0]);
       exit(EXIT_FAILURE);
   }

   in = fmemopen(argv[1], strlen(argv[1]), "r");
   if (in == NULL)
       handle_error("fmemopen");

   out = open_memstream(&ptr, &size);
   if (out == NULL)
       handle_error("open_memstream");

   for (;;) {
       s = fscanf(in, "%d", &v);
       if (s <= 0)
           break;

       s = fprintf(out, "%d ", v * v);
       if (s == \-1)
           handle_error("fprintf");
   }

   fclose(in);
   fclose(out);

   printf("size=%zu; ptr=%s\en", size, ptr);

   free(ptr);
   exit(EXIT_SUCCESS);
}
0

评论区