но в приведенном выше случае он возвращает достаточное количество данных, но указанная длина неверна
Нет, вы не правы в этом. Возвращает то, что говорит, возвращается, 89 байт. Проблема в том, что эти 89 байтов не содержат нулевого терминатора, так что, когда вы printf
буфер, он продолжает работать, печатая то, что уже было в оставшейся части буфера до того, как произошел ваш read
.
То, что вы должны делать (но смотрите предостережение ниже), выглядит примерно так:
len = read(FD, buf, 1500);
printf ("%*.*s\n", len, len, buf);
, чтобы гарантировать, что вы не печатаете за пределами буфера.
То, что вы видите, эквивалентно:
char buff[500];
strcpy (buff, "Hello there");
memcpy (buff, "Goodbye", 7);
printf ("%s", buff);
Поскольку вы не передаете нуль-символ в memcpy, у вас остается следующий буфер:
+---+---+---+---+---+---+---+---+---+---+---+---+
After sprintf: | H | e | l | l | o | | t | h | e | r | e | \0|
+---+---+---+---+---+---+---+---+---+---+---+---+
After memcpy : | G | o | o | d | b | y | e | h | e | r | e | \0|
+---+---+---+---+---+---+---+---+---+---+---+---+
дает строку "Goodbyehere"
.
Оговорка:
Если в вашем потоке данных есть нулевые символы, то printf
не будет работать, так как остановится на первом найденном нулевом символе. Функция read
считывает двоичные данные из файлового дескриптора, и ей не нужно останавливаться на первой новой строке или нулевом символе.
Это было бы эквивалентно:
char buff[500];
strcpy (buff, "Hello there");
memcpy (buff, "Go\0dbye", 8);
printf ("%s", buff);
+---+---+---+---+---+---+---+---+---+---+---+---+
After sprintf: | H | e | l | l | o | | t | h | e | r | e | \0|
+---+---+---+---+---+---+---+---+---+---+---+---+
After memcpy : | G | o | \0| d | b | y | e | \0| e | r | e | \0|
+---+---+---+---+---+---+---+---+---+---+---+---+
дает строку "Go"
.
Если вы действительно хотите обработать строку с нулем или новой строкой в том, что является двоичным каналом, следующее (псевдокод) является одним из способов сделать это:
while true:
while buffer has no terminator character:
read some more data into buffer, break on error or end-of-file.
break on error or end-of-file.
while buffer has at least one terminator character:
process data up to first terminator character.
remove that section from buffer.
Это процесс, который считывает данные до тех пор, пока у вас есть хотя бы одна «единица работы», а затем обрабатывает эти единицы работы до тех пор, пока у вас не останется полная единица работы.