【问题标题】:strange read buffer奇怪的读缓冲区
【发布时间】:2011-07-18 11:26:20
【问题描述】:

这里我遇到了一个关于 linux 中 c 读取函数的奇怪问题。

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

int main(int argc, char** argv){
    int fd=open("a.c",O_RDONLY);
    if(fd==-1){
      fprintf(stderr,"%s\n",strerror(errno));
    }
    char buf[10];
    if(read(fd,buf,9)==-1){
      fprintf(stderr,"%s\n",strerror(errno));
    }else{
      printf("%s\n",buf);
    }
}

我认为 buf 应该初始化为零,所以前 9 个字符读取到缓冲区,最后一个是 '\0',它就像一个字符串。但结果很奇怪,下面是 a.c 文件和这个程序的结果, 交流

    1234567890abcd

结果

    1234567893øþzôo`

似乎这个字符串超出了缓冲区,我不知道发生了什么,谁能帮助我? 谢谢。

【问题讨论】:

    标签: c buffer


    【解决方案1】:

    当你打印一个没有以'\0'结尾的字符数组时,printf 将打印所有字符,直到它在内存中找到'\0'。在这种情况下,看起来像“1234567893øþzôo”后面跟着“\0”。请注意,printf 不知道 'buf' 数组的大小,因此它甚至会打印出现在 buf 数组末尾之后的那些字符。

    正如您所建议的,最好将整个缓冲区设置为 0 或在末尾显式添加“\0”(如下面的代码所示)。

       buf[9] = '\0';
    

    【讨论】:

      【解决方案2】:

      您说“我认为 buf 应该初始化为零”。编译器不会自动为您执行此操作,因此您需要自己执行此操作:

      char buf[10];
      memset(buf, 0, sizeof(buf));
      

      在初始化缓冲区之前,你无法保证它的内容是什么。

      【讨论】:

      • 甚至char buf[10] = {0};
      • 设置为 0 是可以的,但默认情况下为什么编译器没有将 buf 初始化为零?我将代码更改为static char buf[10],然后它有正确的输出,我认为char buf[10]static char buf[10] 具有相同的静态持续时间,并且应该以相同的方式默认初始化
      • 好的。我明白了,它们是不同的,我理解错误。 char buf[10] 不会初始化,因为它在 main() 块中。谢谢你们。
      • 无论您在哪里定义缓冲区,如果您不提供初始化程序或在某些时候显式初始化缓冲区,则无法保证缓冲区的内容是什么。
      • 但是如果在功能块之外定义它,那么它是一个全局变量,它会默认初始化为零。
      【解决方案3】:

      ISTM 您的缓冲区不是以零结尾的,因为您只读取了 9 个字符。更改代码的最后一部分:

        if(read(fd,buf,9)==-1){
          fprintf(stderr,"%s\n",strerror(errno));
        }else{
      
          /* add this */ 
          buf[9] = '\0';
      
          printf("%s\n",buf);
        }
      }
      

      如果添加它会发生什么?

      【讨论】:

        【解决方案4】:

        你应该将 buf 初始化为全 0。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-10-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-08-12
          • 1970-01-01
          相关资源
          最近更新 更多