C - проблема очистки в stdin при чтении ввода больше принятого - PullRequest
0 голосов
/ 22 марта 2020

Я кодирую интерактивную игру судоку и анализирую команды с консоли.

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

, поэтому я выделил память для массива char длиной 256 и прочитал этот ввод с помощью функции fgets, а затем передал его функции парсера, вот мой код для этой части - Примечание что вход - это вход, который я передал от fgets fun c.

Command parseCommand(char *input, int upperBound, MODE* mode){

Command command;
char* token;
char *copyInput = (char*) malloc(strlen(input)*sizeof(char));

if(copyInput == NULL){
    printf("Error: parseCommand has failed\n");
    free(copyInput);
    exit(EXIT_FAILURE);
}

command.cmd = ERROR;
strcpy(copyInput,input);
token = strtok(input,delim);

if(strlen(copyInput) > 256){
    command.cmd = MAX_ARGS_REACHED;
    clear();
}...//More code following to that but irrelvant

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

void clear(){
int c = 0;
while ((c = getchar()) != '\n' && c != EOF) { }

}

Надеюсь получить помощь здесь спасибо!

edit - вот код, показывающий, как я читаю ввод и передаю его функции выше -

void runGame(){
Game* game;
char* input = (char*) malloc(256 * sizeof(char));
if(input == NULL){
    printf("Error: Program has failed!\n");
    free(input);
    exit(EXIT_FAILURE);
}

printf("Welcome to Sudoku Game!\n");
game = createGame();

while(1){

    Command command;
    printf("Please enter a Command\n");
    if(!fgets(input,ARRSIZE,stdin)){/*checks if reading user input failed or EOF*/
        exitCommand(game);
        free(input);
        return;
    }

    command = parseCommand(input,game->rows,&game->mode);//More code following to that

Ответы [ 3 ]

1 голос
/ 22 марта 2020

Неправильный размер входного массива.

Я хочу ограничить пользовательские команды до 256 символов
ARRSIZE = 256

В дополнение к Неадекватное выделение памяти , что, на мой взгляд, является ключевой проблемой OP, для чтения строки ввода требует большего массива.

strlen(copyInput) > 256 никогда не будет истинным с fgets(input,256,stdin) , Длина строки в буфере input будет не более 255.

Не ясно, учитывает ли OP часть ввода Enter или '\n'. fgets() делает.

A строка требуется длина не менее 257 для отключения strlen(copyInput) > 256.

Для чтения строки до 257 (без учета потенциал '\n'), код должен использовать буфер длиной 256 + 1 + 1 + 1.

#define CMD_N 256
//                      extra to test too long, \n, \0  
#define BUFFER_N (CMD_N + 1                    + 1 + 1)


char* input = malloc(BUFFER_N);
....
if(!fgets(input,BUFFER_N,stdin)) {
  buffer[strcspn(buffer, "\n")] = '\0';  // lop off potential \n
  ....

if(strlen(copyInput) > CMD_N) {
0 голосов
/ 23 марта 2020

Предложить:

Следуйте вызову fgets() с:

int ch;
while( (ch = getchar()) != EOF && ch != '\n' ){;}

Так как это будет правильно использовать любые оставшиеся данные в stdin

0 голосов
/ 22 марта 2020

Как минимум, эта проблема

Неадекватное выделение памяти

Требуется +1 для нулевого символа . (В ролях не требуется C)

// char *copyInput = (char*) malloc(strlen(input)*sizeof(char));
char *copyInput = malloc(strlen(input) + 1);
strcpy(copyInput,input);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...