Я использую gcc в Ubuntu 4.6.1 и SUSE 4.6.2 со следующей командой
gcc gets_s.c
Мой исходный код
// Read and Display Lines
// gets_s.c
#include <stdio.h>
int main(void)
{
char first_name[11];
char last_name[11];
printf("First Name : ");
gets_s(first_name, 11);
printf("Last Name : ");
gets_s(last_name, 11);
puts(first_name);
puts(last_name);
return 0;
}
Уточняю мой вопрос:
Принципиальной проблемой для меня является однозначное соответствие между введенными строками и сохраненными строками.
В случае успеха разница между fgets и gets_s заключается в том, что fgets включает в себя признак новой строки, а gets_s заменяет признак новой строки на нулевой признак, чтобы поддерживать однозначное соответствие между введенными строками и успешными вызовами gets_s.
Для ввода, превышающего длину буфера, fgets принимает количество символов, которое помещается в буфер, а остальные оставляет во входном буфере для следующих fgets.
В стандарте (K.3.5.4.1) указано, что с gets_s (в отличие от gets) требуется новая строка, конец строки или ошибка чтения в пределах n-1 символов. Следовательно, переполнение является нарушением ограничений времени выполнения. Если есть нарушение ограничения времени выполнения, первый символ в буфере устанавливается в нулевой символ, а символы во входном буфере stdin считываются и отбрасываются до тех пор, пока не будет прочитан символ новой строки, произойдет конец файла. или возникает ошибка чтения.
Соответственно в случае успеха я ожидал:
>fgets
First Name : Chris
Last Name : Szalwinski
Chris
Szalwinski
>
>gets_s
First Name : Chris
Last Name : Szalwinski
Chris
Szalwinski
>
При переполнении я ожидал другого поведения от fgets и gets_s. Другими словами,
>fgets
First Name : Christopher
Last Name : Christophe
r
>
>gets_s
First Name : Christopher
Last Name : Szalwinski
Szalwinski
>
Обратите внимание, как я ожидал, что get_s полностью удалит содержимое первой строки ввода.
Если основная проблема заключается во взаимно однозначном соответствии между введенными и сохраненными строками, что важно при отладке, нам все равно нужно написать собственную функцию (аналог getline K&R)
char *gets_s(char *s, int n)
{
int i, c;
for (i = 0; i < n - 1 && (c = getchar()) != EOF && c != (int)'\n'; i++)
s[i] = c;
s[i] = '\0';
while (n > 1 && c != EOF && c != (int)'\n')
c = getchar();
return c != EOF ? s : NULL;
}
С такой функцией сохраняется однозначное соответствие, буфер переполняется и не нарушается ограничение времени выполнения.
Правильно ли я делаю такой вывод.