apue中memstr.c的究极困惑解决

17 篇文章 0 订阅

这两天因为fmemopen这个函数导致自己一直很迷惑为什么memstr.c中最后一个输出就是不加null字节.

在自己

  • 查看http://man7.org/linux/man-pages/man3/fmemopen.3.html的文档
  • 查看apue英文版
  • 以及苦思冥想了大概4小时之后
    终于找到了网上有个前辈对这里的思考

Third, a null byte is written at the current position in the stream whenever we
increase the amount of data in the stream’s buffer and call fclose, fflush, fseek,fseeko, or fsetpos

中间是and 所以要同时满足这两个条件才会增加一个null字节。因为最后我们的内存流中其实是还有24个字节的,只是把当前位置移动到了开头的位置,所以其实不满足前面的数据量增加 ,所以最后一段代码并不会增加一个null字节。

下面可以看我的代码运行一下memstr.c

// 2020年02月26日22:31:54   52行处还是不懂,卡了40分钟,自闭
// 2020年02月27日18:06:23  自闭4个多小时终于理解了,因为5.7的那个源码题
#include "apue.h"

#define BSZ 48

int
main()
{
    FILE *fp;
    char buf[BSZ];
    char data[62];

    memset(buf, 'a', BSZ-2);
    buf[BSZ-2] = '\0';
    buf[BSZ-1] = 'X';
    // 通过w+读写申请内存流,那么就一开始截断文件(这里是buf)从0开始
    if ((fp = fmemopen(buf, BSZ, "w+")) == NULL)
        err_sys("fmemopen failed");
    printf("initial buffer contents: %s\n", buf);
    fprintf(fp, "hello, world");
    printf("before flush: %s\n", buf);
    fflush(fp);
    printf("after fflush: %s\n", buf);
    // 这里导致偏移量到了12
    printf("len of string in buf = %ld\n", (long)strlen(buf));

    memset(buf, 'b', BSZ-2);
    buf[BSZ-2] = '\0';
    buf[BSZ-1] = 'X';

    printf("initial buffer contents: %s\n", buf);

    fprintf(fp, "hello, world");

    printf("hello world buffer contents: %s\n", buf);

    // fseek让缓冲区刷新,然后就是从12的位置向后添加hello, world\0,然后再fseek到文件开始部分
    // To set file pointer to the beginning of the file
    fseek(fp, 0, SEEK_SET); // We can use rewind(fp); also

    printf("after  fseek: %s\n", buf);
    printf("buffer[26] is still b: %c\n", buf[26]);
    printf("len of string in buf = %ld\n", (long)strlen(buf));

    // 可以通过这样读取出,虽然seek的当前位置变成了开头的地方,但是数量量其实还是有24个Bytes
    fgets ( data, 60, fp );
    printf("\nwhen SEEK_POS = 0.fmemopen data is %s\n And fmemopen still has %d bytes\n\n", data,strlen(data));

    // 我的读取操作完还变动seek位置,所以我们操作完再搞回去
    fseek(fp, 0, SEEK_SET);

    memset(buf, 'c', BSZ-2);
    buf[BSZ-2] = '\0';
    buf[BSZ-1] = 'X';
    fprintf(fp, "hello, world");
    // fclose刷新流,然后就是在文件开始部分写入hello, world,但是竟然没有null截断??????

    /*
    Third, a null byte is written at the current position in the stream whenever we
    increase the amount of data in the stream’s buffer <font color=red>**and**</font> call fclose,
     fflush, fseek,fseeko, or fsetpos

   中间是<font color=red>**and**</font> 所以要同时满足这两个条件才会增加一个null字节。
    <font color=red>**因为最后我们的内存流中其实是还有24个字节的,只是把当前位置移动到了开头的位置,
    所以其实不满足前面的数据量增加**</font> ,所以最后一段代码并不会增加一个null字节。
    */
    fclose(fp);
    printf("after fclose: %s\n", buf);
    printf("len of string in buf = %ld\n", (long)strlen(buf));

    return(0);
}

initial buffer contents: 
before flush: 
after fflush: hello, world
len of string in buf = 12
initial buffer contents: bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
hello world buffer contents: bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
after  fseek: bbbbbbbbbbbbhello, world
buffer[26] is still b: b
len of string in buf = 24

when SEEK_POS = 0.fmemopen data is bbbbbbbbbbbbhello, world
 And fmemopen still has 24 bytes

after fclose: hello, worldcccccccccccccccccccccccccccccccccc
len of string in buf = 46


感谢前辈: https://www.cnblogs.com/ittinybird/p/4483329.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这个错误是因为在编译过程找不到apue.h文件导致的。通常情况下,apue.h是一个头文件,用于包含在C程序使用的一些函数和定义。在Linux下,这个头文件通常是由一个库文件提供的。根据你提供的信息,你可能没有正确设置编译环境,或者没有将apue.h头文件包含在你的编译命令。 为了解决这个问题,你可以按照以下步骤进行操作: 1. 确保你已经正确安装了apue库文件。可以使用命令`apt-get install libapue-dev`来安装这个库文件。 2. 确保你的编译命令包含了正确的头文件路径。你可以使用`-I`选项来指定头文件的路径。例如,`gcc -o myprogram myprogram.c -I/path/to/apue/include`。 3. 如果你已经安装了apue库文件,但是还是找不到apue.h文件,那么可能是因为头文件没有正确地安装到系统目录。你可以手动将apue.h文件复制到/usr/include/目录下。可以使用命令`cp /path/to/apue/include/apue.h /usr/include/`来复制文件。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Unix环境高级编程——解决第一个问题“apue.h: No such file or directory”](https://blog.csdn.net/qq_41899773/article/details/107376991)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [unix高级编程时遇到apue.h 报错问题](https://blog.csdn.net/zhuqinfeng/article/details/50468178)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值