Системный вызов read не обнаруживает конец файла
Я пытаюсь создать функцию, которая читает весь файл, используя определенный размер чтения, который может измениться в любое время, но системный вызов read не сохраняет символы в буфере должным образом, пока я пытаюсь печатать только до конец файла, как это:
#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
и read, чтобы справиться с этим, open предназначен только для тестирования, и я не понимаю, почему он это делает, обычно read возвращает количество байтов, прочитанных в этом файле, и 0, если он достигает конца файла, так что это немного странно видеть это.
2 ответа
Помимо очень элегантного решения, предоставленного ответом chux, вы также можете просто завершить буфер (и с этим только сделать его 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);
}
В печати массива символов отсутствует нулевой символ. Это UB с "%s"
,
printf("%s", buffer); // bad
Чтобы ограничить печать массива символов без нулевого символа, используйте модификатор точности. Это напечатает массив символов с таким количеством символов или нулевым символом - который когда-либо будет первым.
// printf("%s", buffer);
printf("%.*s", rd, buffer);
Подсказка по отладке: печатайте текст с часовыми, чтобы четко указать результат каждого отпечатка.
printf("<%.*s>\n", rd, buffer);