Ваша попытка не очень подражают gets()
, так как gets()
просто хранит положить байт в до тех пор, пока не будет достигнут конец линии. Вы должны понимать, что gets()
опасен и его следует избегать. Он не обеспечивает защиту от переполнения буфера. Таким образом, подражаем также подражание.
Учитывая, что ваша попытка имеет несколько недостатков, которые я вижу. Во-первых, он переходит в полный размер входного буфера. Это не оставляет вам места для хранения терминатора NUL, если строка ввода составляет 20 байтов или дольше. Это означает, что вы можете попытаться сохранить \0
по адресу cvalue[20]
, который находится за пределами границы массива. Вы можете исправить это за счет сокращения ваш for
цикл одним:
for(iloop=0;iloop<19;iloop++) // for loop to get the string char by char
Второй недостаток заключается в том, что вы не проверить, если scanf()
вызов успешен. Если вы обнаружили неисправность, вы также должны покинуть цикл:
if (scanf("%c",&cvalue[iloop]) != 1) { //getting input
break;
}
Ниже была моя попытка создать более безопасную версию gets()
реализованный с scanf()
.
char *getsn (char *s, size_t sz) {
char c;
char fmt[sizeof(sz) * CHAR_BIT + sizeof("[^\n]")];
if (sz == 0) return 0;
if (sz == 1) {
s[0] = '\0';
return s;
}
s[sz-2] = '\0';
snprintf(fmt, sizeof(fmt), "%%%lu%s", (unsigned long)sz-1, "[^\n]");
switch (scanf(fmt, s)) {
case 0: s[0] = '\0';
scanf("%c", &c);
return s;
case 1: scanf("%c", &c);
if (s[sz-2] != '\0' && c != '\n') {
ungetc(c, stdin);
}
return s;
default: break;
}
return 0;
}
Безопаснее версия использует snprintf()
для создания строки формата, который ограничивает количество символов, должны храниться в scanf()
. Поэтому, если предоставленный параметр sz
равен 100, итоговая строка формата будет "%99[^\n]"
. Затем он обязательно отключит \n
от входного потока, если он действительно встретился.
Пожалуйста, найдите время, чтобы узнать, как [форматировать свои вопросы] (http://stackoverflow.com/editing-help). Я также сформулировал ваш вопрос, чтобы лучше соответствовать формату SO. Сначала задайте вопрос четко, а затем покажите свою текущую попытку. –