Я использую GCC на Ubuntu 4.6.1 и 4.6.2 SUSE с помощью следующей командыНеопределенная ссылка на gets_s?
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) требуется строка новой строки, EOF или ошибка чтения в пределах 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 полностью удалит содержимое первой строки ввода.
Если основной проблемой является взаимно однозначное соответствие между линиями ввода и линий сохраняются, что очень важно при отладке, нам все еще нужно, чтобы написать свою собственную функцию (по аналогии с K GetLine & 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;
}
С такой функцией поддерживается взаимно однозначное соответствие, буфер насыщен и не существует нарушения ограничения времени выполнения.
Правильно ли я делаю это заключение.
@ Vlad: 'get' абсолютно бесполезен. Именно поэтому C11 полностью удаляет его. –
Я просто попробовал сам '-std = c11'; он все еще не находит 'gets_s'. И 'get_s', наряду с остальной частью C11 Annex K« Интерфейсы проверки границ », * необязательно *, даже для полностью соответствующих реализаций C11 (которые gcc еще нет). Реализация может определять макрос '__STDC_LIB_EXT1__' и предоставлять интерфейсы - или нет. –
Итак, в основном, используйте 'fgets'. – nneonneo