Функция gets() и нулевой байт '\0' на входе

Будет ли функция gets() из языка C (например, из glibc) остановлена, если она прочитает нулевой байт ('\0') из файла?

Быстрый тест: echo -ne 'AB\0CDE'

Спасибо.

PS этот вопрос возникает из комментариев к этому вопросу: возврат к libc - проблема

PPS функция gets опасна, но речь идет о самой этой функции, а не о том, использовать ее или нет.


person osgx    schedule 21.02.2011    source источник
comment
Обратите внимание, что вы не должны использовать gets: stackoverflow.com/questions/1694036/   -  person Jeremiah Willcock    schedule 21.02.2011
comment
@Jeremiah Willcock, конечно, но этот вопрос возникает после простейшего примера переполнения стека, в котором используется gets, чтобы проиллюстрировать его опасность (см. связанный вопрос).   -  person osgx    schedule 21.02.2011


Ответы (2)


Поведение gets() заключается в том, что он останавливается, когда встречается символ новой строки или если встречается EOF. Ему все равно, если он прочитает \0 байта.

Стандарт C99, 7.19.7.7

Краткий обзор

   #include <stdio.h>

   char *gets(char *s);

Описание

Функция gets считывает символы из входного потока, на который указывает stdin, в массив, на который указывает s, до тех пор, пока не встретится конец файла или не будет прочитан символ новой строки. Любой символ новой строки отбрасывается, а нулевой символ записывается сразу после последнего символа, считанного в массив.

Из документации GNU libc: http://www.gnu.org/software/libc/manual/html_node/Line-Input.html#Line-Input

— Устаревшая функция: char * gets (char *s)

Функция gets считывает символы из потока stdin до следующего символа новой строки и сохраняет их в строке s. Символ новой строки отбрасывается (обратите внимание, что это отличается от поведения fgets, который копирует символ новой строки в строку). Если get обнаруживает ошибку чтения или конец файла, он возвращает нулевой указатель; в противном случае он возвращает s.

person wkl    schedule 21.02.2011

Он не остановится на нулевом байте.

$ cat gets22.c
int main(int argc, char **argv) {
  char array[8];
  gets(array);
  printf("%c%c%c%c%c%c%c\n",array[0],array[1],array[2],array[3],array[4],array[5],array[6],array[7]);
  printf("%d %d %d %d %d %d %d\n",array[0],array[1],array[2],array[3],array[4],array[5],array[6],array[7]);
}

$ gcc gets22.c  -o gets22

$ echo -ne 'AB\0CDE'| ./gets22
ABCDE
65 66 0 67 68 69 0
person osgx    schedule 21.02.2011