Как изменить, если еще оператор для переключения? - PullRequest
0 голосов
/ 17 января 2019

Я не понимаю / не знаю, как изменить мои операторы if else, чтобы они стали оператором switch для дел. Пожалуйста помоги! Мне просто нужно поменять мои операторы if else на переключатель, и мое назначение будет завершено! Его полностью работает и функционирует!

Эта программа на С предоставляет основную функцию, которая поддерживает историю, похожую на bash способность; Основная цель кругового буфера состоит в том, чтобы повторно отображать подсказку для пользователя, и каждая подсказка назначает входной номер, начиная в 1. Каждая строка, введенная в кольцевой буфер, сохраняется до тех пор, пока не будет перезаписана, буфер допускает только до 5 строк сохраненного ввода, FIFO (First in, first out).

Предоставление пользователю 4 варианта команды: ! x: с x означает выбранный номер строки и восклицательный знак ("!") означает повторите (абсолютную) строку ввода с номером x. Это работает только если эта строка является одной из сохраненные команды. Эта команда отобразит исходную строку ввода, а также хранение копии. Если аргумент x недействителен, появится сообщение об ошибке.

выход (с учетом регистра): завершает работу программы.

история (с учетом регистра): печать сохраненных команд

parse (с учетом регистра): токенизировать строку ввода номер x, эта строка ввода не должна быть хранится в буфере, но вместо этого отображать каждое слово в отдельной строке.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define CIRCULAR_HISTORY_BUFFER 5 
#define CHARACTER_LENGTH 128

void CircularHistoryBuffer()
{
char memory[CIRCULAR_HISTORY_BUFFER][CHARACTER_LENGTH];
char command_line[CHARACTER_LENGTH];
int data, n, i;
int number = 0; 
while(1) 
{
    printf("%d>", number + 1);

    fgets(command_line, CHARACTER_LENGTH - 1, stdin);
    for(i = 0; i < CHARACTER_LENGTH; i++)
    {
        if(command_line[i] == '\n')
        {
            command_line[i] = '\0';
            break;
        }
    }
    if(command_line[0] == '!')
    {
        n = atoi(command_line + 1);
     if(n < number - CIRCULAR_HISTORY_BUFFER + 1 || n > number || n <= 0)
        {
            printf( "%d: Not found\n", n);
        }
        else
        {
            data = (n - 1) % CIRCULAR_HISTORY_BUFFER;
            printf("%s\n", memory[data]);
            strcpy(memory[number % CIRCULAR_HISTORY_BUFFER], memory[data]);
            number++;
        }
    }
    else if(strcmp(command_line, "exit") == 0)
    {
        exit(0);
    }
    else if(strcmp(command_line, "history") == 0)
    {
        if(number <= CIRCULAR_HISTORY_BUFFER)
        {
            for(i = 0; i < number; i++)
            {
                printf("%d\t%s\n", i + 1, memory[i]);
            }
        }
        else 
        {
            n = number - CIRCULAR_HISTORY_BUFFER + 1;
            data = number % CIRCULAR_HISTORY_BUFFER;
            for(i = data; i < CIRCULAR_HISTORY_BUFFER; i++)
            {
                printf("%d\t%s\n", n++, memory[i]);
            }
            for(i = 0; i < data; i++)
            {
                printf("%d\t%s\n", n++, memory[i]);
            }
        }
    }
    else if(strncmp(command_line, "parse", 5) == 0)
    {
        n = atoi(command_line + 5);
     if(n < number - CIRCULAR_HISTORY_BUFFER + 1 || n > number || n <= 0)
        {
            printf("%d: event not found\n", n);
        }
        else
        {
            data = (n - 1) % CIRCULAR_HISTORY_BUFFER;
            for(i = 0; i < strlen(memory[data]); i++)
            {
                if(memory[data][i] == ' ')
                {
                    printf("\n");
                }
                else
                {
                    printf("%c", memory[data][i]);
                }
            }
            printf("\n");
        }
    }
    else
    {
        strcpy(memory[number % CIRCULAR_HISTORY_BUFFER], command_line);
        number++;
    }
  }
 }

int main()
{
  CircularHistoryBuffer();

return 0;
}

Ответы [ 3 ]

0 голосов
/ 17 января 2019

switch -условие будет работать только с целочисленными значениями. Существует switch -общение:

switch(a) { case '1': doSomething(); break; // if you forget break operator, than second корпус also will invoke and so one case '2': doSomethingElse(); break; default: doSomethingElse2(); }

Вы можете использовать switch -статмент, если вам нужно работать с целочисленными значениями / константами из определенного диапазона.

0 голосов
/ 17 января 2019

в настоящее время ваш код выглядит так:

  if(command_line[0] == '!')
   {
       <recall>
   }
   else if(strcmp(command_line, "exit") == 0)
   {
       <exit>
   }
   else if(strcmp(command_line, "history") == 0)
   {
       <historic>
   }
   else if(strncmp(command_line, "parse", 5) == 0)
   {
       <parse>
   }
   else
   {
       <other>
   }

использование переключателя даст что-то вроде этого:

   switch (command_line[0]) {
    case '!':
        <recall>
        break;
    case 'e':
       if(strcmp(command_line + 1, "xit") == 0)
       {
         <exit>
       }
       else
       {
         <other>
       }
       break
    case 'h':
       if(strcmp(command_line + 1, "istory") == 0)
       {
         <historic>
       }
       else
       {
         <other>
       }
       break
    case 'p':
       if(strncmp(command_line + 1, "arse", 4) == 0)
       {
         <parse>
         break;
       }
       // no fallthrough
    default:
      {
         <other>
      }
    }

Это менее читабельно, облегчает появление ошибок, если оно должно быть изменено, и не оказывает положительного влияния на скорость, если вы ожидаете

Для меня не делайте этого ... но спросите себя о strcmp но strncmp в одном случае

0 голосов
/ 17 января 2019

В этом случае не имеет особого смысла использовать оператор switch, так как вы пытаетесь выполнить несколько сравнений строк.

Вместо этого вы можете выполнить поиск по таблице на основе таблицы, отсортированной в алфавитном порядке:

const char* STR_TABLE[] =  // must be sorted in alphabetic order
{
  "exit",
  "history",
  "parse",
  ...
};

const size_t STR_TABLE_SIZE = sizeof(STR_TABLE) / sizeof(STR_TABLE[0]);

Затем вы можете найти в таблице правильную строку. Наивной реализацией является цикл for:

for(size_t i=0; i<STR_TABLE_SIZE; i++)
{
  if(strcmp(STR_TABLE[i], user_input)==0)
  {
    // found, do something
    break;
  }
}

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

int strcmp_wrapper (const void* obj1, const void* obj2)
{
  return strcmp(obj1, *(const char**)obj2);
}

const char** result = bsearch(user_input, 
                              STR_TABLE,
                              STR_TABLE_SIZE,
                              sizeof(const char*),
                              strcmp_wrapper);

if(result != NULL)
{
  printf("User picked option %s at index %d.", *result, (int)(result - STR_TABLE));
}                               
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...