读取系统调用没有检测到文件结束

时间:2017-01-13 18:53:28

标签: c string posix c-strings

我试图创建一个函数,使用可随时更改的特定读取大小读取整个文件,但读取系统调用并未将字符正确存储在缓冲区中,到目前为止我&# 39; m只是尝试打印到文件末尾,如下所示:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>

# define READ_SIZE (42)

int main(int argc, char **argv)
 {
   int fd;
   int rd;
   char *buffer;

   buffer = malloc(READ_SIZE);
   fd = open(argv[1], O_RDONLY);
   while ((rd = read(fd, buffer, READ_SIZE)) > 0)
    {
       printf("%s", buffer);
    }
    return (0);
 }

这是我试图阅读的文件:

test1234
test123
test1
test2
test3
test4
test

这是我程序的输出:

test123
test12
test1
test2
test3
test4
testest123
test12
test1
test2
test3
test4
tes

我只能使用malloc,并且读取处理这个,open只是用于测试,我不明白它为什么这样做,通常read返回该文件中读取的字节数,如果它到达文件末尾则为0,所以看到这个有点奇怪。

2 个答案:

答案 0 :(得分:2)

字符数组的打印缺少空字符。这是UB "%s"

printf("%s", buffer);  // bad

要限制打印缺少空字符的字符数组,请使用精度修饰符。这将打印字符数组到多个字符或空字符 - 这是第一个。

// printf("%s", buffer);
printf("%.*s", rd, buffer);

调试提示:使用标记打印文本以清楚地指示每个打印的结果。

printf("<%.*s>\n", rd, buffer);

答案 1 :(得分:1)

除了chux's answer提供的非常优雅的解决方案之外,你还可以在打印前明确地终止缓冲区(并且只使它成为C-“字符串”):

while ((rd = read(fd, buffer, READ_SIZE-1)) > 0) /* read one less, to have a spare 
                                                    char available for the `0`-terminator. */
{
  buffer[rd] = '\0';
  printf("'%s'", buffer);
}