2014-01-21 5 views
-2

Для моего назначения практики мне нужно использовать либо gets(), либо fgets(). Я выбрал fgets() как более безопасный.fgets() Не игнорирует новую строку

Первый вход предназначен для хранения максимум 5 символов. Итак, я дал массив символов размером 6 для размещения конечного «\ 0».

Я нашел fgets() вопрос об этом добавив завершающую «\ п» при нажатии Enter (с помощью стандартного ввода с fgets())

Я сделал несколько исследований, и нашел цикл, чтобы попытаться избавиться от этого. Тем не менее, он, похоже, не работает, и я не могу, чтобы жизнь меня определяла, почему.

Его все еще пропускают следующий вход, когда я печатаю 5 символов.

Вот код:

#include <stdio.h> 
#include <string.h> 

int main(void) 
{ 
    //Declare char arrays 
    char arcInputString5[6]; 
    char arcInputString10[11]; 
    char arcInputString15[16]; 
    char arcInputString20[21]; 
    int  clean1, clean2, clean3, clean4; 
// int  nStrLen1, nStrLen2, nStrLen3, nStrLen4; 
// nStrLen1 = nStrLen2 = nStrLen3 = nStrLen4 = 0; 

printf("\nPlease Input String 1 - Max Length 5: "); 
//gets(arcInputString5); 
fgets(arcInputString5, 6, stdin); 

for(clean1 = 0; clean1 < strlen(arcInputString5); clean1++) 
{ 
    if(arcInputString5[clean1] == '\n' || arcInputString5[clean1] == '\r') 
    { 
     arcInputString5[clean1] = '\0'; 
     break; 
    } 
} 

printf("\nPlease Input String 2 - Max Length 10: "); 
//gets(arcInputString10); 
fgets(arcInputString10, 10, stdin); 

printf("\nPlease Input String 3 - Max Length 15: "); 
//gets(arcInputString15); 
fgets(arcInputString15, 15, stdin); 

printf("\nPlease Input String 4 - Max Length 20: "); 
//gets(arcInputString20); 
fgets(arcInputString20, 20, stdin); 

printf("\nThankyou For Your Inputs - They Are Shown Back To You Below\n"); 

puts(arcInputString5); 
puts(arcInputString10); 
puts(arcInputString15); 
puts(arcInputString20); 

printf("\nThe String Lengths For Each Input Are Listed Below"); 

printf("\n%d", strlen(arcInputString5)); 
printf("\n%d", strlen(arcInputString10)); 
printf("\n%d", strlen(arcInputString15)); 
printf("\n%d", strlen(arcInputString20)); 

}

Ive пытался несколько способов сделать для цикла, например, используя число 6 вместо "STRLEN (arcInputString5)"

Любая помощь будет оценена.

РЕДАКТИРОВАТЬ:

Пример входных данных:

asd d 

ПРИМЕР ВЫХОД:

Please Input String 2 - Max Length 10: //skips this 
Please Input String 3 - Max Length 15: //this is the next line for input 
+0

Пожалуйста, укажите точный ввод и вывод программы. –

+1

Не столько «добавление новой строки», как «не удаление новой строки». Клавиша Enter предоставляет новую строку; функция 'gets()' удаляет это из возвращаемой строки, но 'fgets()' does not - это, по крайней мере, дает вам возможность определить, была ли у вас полная строка или была ли урезана линия ввода из-за нехватки места , –

+2

Как правило, не ограничивайте ввод только 5 символами; разрешить (ради аргумента) 256 символов ввода, а затем проверить, что пользователь не вводил более 5 символов (кроме новой строки). Это в значительной степени устраняет проблемы, связанные с необходимостью очистки дополнительных данных от длинных строк. Фактически, я бы использовал 4096 в качестве длины по умолчанию для ввода (а не только 256), но выберем любое достаточно большое значение, которое вряд ли вызовет проблемы. –

ответ

2

fgets() читает один символ меньше, чем заданный размер буфера из стандартного ввода, а затем добавляет NUL -персонаж. Таким образом, в вашем случае с буфером ввода из 6 символов, , он считывает «asd d» в arcInputString5, а символ новой строки, который завершает ввод строки, по-прежнему непрочитан.

Следующий fgets() затем считывает (только) этот символ новой строки в arcInputString10.

Вам нужно иметь размер буфера (как минимум) 7, чтобы прочитать пять символов «asd d», включая символ новой строки из stdin.

То же самое относится к вашим другим буферам, используемым для fgets().

Добавлено: Как Джонатан Леффлер правильно заметил, лучший способ поставить «большой» входной буфер fgets() и проверить фактическую длину пользовательского ввода после чтения одной строки.

Следует также отметить, что fgets() возвращает NULL, если ни один символ не может быть прочитан вообще (конец файла), поэтому вы должны проверить возвращаемое значение.

+0

Согласен, но обратите внимание, что если пользователи ошибочно принимают «supercalifragilisticexpialidocious» типов муравьев, а не просто «супер», тогда код должен восстановиться с чрезмерного ввода. И пользователи будут делать такие ошибки. –

+0

@JonathanLeffler: Вы совершенно правы, мой ответ объясняет только * почему * он не работает должным образом. Ваш комментарий http://stackoverflow.com/questions/21270323/fgets-not-ignoring-new-line/21270524?noredirect=1#comment32049166_21270323 к вопросу описывает лучшее решение. –

+0

Спасибо Мартину за четкое объяснение. Это очень помогло. –

0

Позвоните getchar(), чтобы получить символ новой строки из входного потока, прежде чем запрашивать следующий вход пользователя.

Я хотел бы использовать следующую простую функцию для очистки входного потока

void clear() { 
    while(getchar() != '\n'); 
} 
1

Изменить к :
arcInputString5[7];
fgets(arcInputString5, 7, stdin);

Вам нужно дать место для '\ n' и '\ 0' персонажей.

valter

Смежные вопросы