Ошибка сегментации с использованием strcmp и char * arr [] - PullRequest
0 голосов
/ 10 февраля 2019

Я работаю над созданием оболочки и давно не пользуюсь Си.У меня правильно запускается оболочка, но когда я пытаюсь сравнить пользовательский ввод с массивом строк, я получаю ошибку сегментации.Я планировал добавить операторы casce в цикл for, чтобы инициировать каждый из процессов после их вызова пользователем.Я не включил их, так как пытался выяснить, как сделать так, чтобы пользовательский ввод соответствовал значению в моем массиве строк.При отладке я получал только первый символ значения builtins [j], который делает, так как это указатель вправо.Однако я застрял и мог бы использовать некоторые идеи для того, почему это не возвращает 0, когда я ввожу «выход».Спасибо

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>

//This code is for creating a basic shell
void init_shell(int num, char *prompt[]){
    char s1[] = "-p"; 
    int result;
    if(num>1){
    result = strcmp(s1, prompt[1]);
        if(result==0){
            printf("%s>$", prompt[2]);

        }else{
        printf("308sh>$");
        }
    }
    //printf("%s\n %s\n %s\n %d\n", prompt[0], prompt[1], prompt[2], result);
    else{
        printf("308sh>$");
    }

}

// Бесконечный цикл для принятия пользовательского ввода, пока он не закроется

int main(int argc, char *argv[]){


    const char *builtins[7];    
    builtins[0] = "exit\n";
    builtins[1] = "pid\n";
    builtins[2] = "ppid\n";
    builtins[3] = "cd\n";
    builtins[4] = "pwd\n";
    builtins[5] = "set\n";
    builtins[6] = "get\n";

    char usr_in[]="";
    char cmp[]="";
    while(1==1){
        init_shell(argc, argv);//intial prompt for the shell
        fgets(usr_in,100,stdin); 

    //Check for builtin Commands

        int cmds_size = 7;
        int j=0;
        int res;

        for(j; j<cmds_size; j++){

            res=strcmp(usr_in, hold);
            if(res==0){

            printf("Execucting\n");
            }
            else{
                printf("no command\n");
            }
        }

    }

    return(0);
}

1 Ответ

0 голосов
/ 10 февраля 2019

Проблема здесь в том, что вы записываете пользовательские данные в буфер, который недостаточно велик для хранения чего-либо, кроме нулевого терминатора.

char user_in[] = "";

В приведенной выше строке сообщается компилятору C, чтовам нужно достаточно места для хранения [ '\0' ], то есть одного байта.Компилятор C не знает, что вы можете позже написать 100-байтовую строку в этот буфер.

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

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

char user_in[101];
for(int i = 0; i < sizeof(user_in) / sizeof(user_in[0]); i++) {
  user_in[i] = 0; // Since this is allocated on the stack *in main*, this
                  // shouldn't be necessary
}

Вот один пример того, какВы можете переписать свой основной метод:

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

typedef enum { false, true } bool; // If you don't have this
                                   // defined already

int main(int argc, char *argv[]) {

  const char *builtins[7];    
  builtins[0] = "exit\n";
  builtins[1] = "pid\n";
  builtins[2] = "ppid\n";
  builtins[3] = "cd\n";
  builtins[4] = "pwd\n";
  builtins[5] = "set\n";
  builtins[6] = "get\n";

  char user_in[101];
  for(int i = 0; i < sizeof(user_in) / sizeof(user_in[0]); i++) {
    user_in[i] = 0;
  }

  while(1) {
    printf("Enter a command: ");
    fgets(user_in, 100, stdin);

    bool found = false;
    for(int i = 0; i < sizeof(builtins) / sizeof(builtins[0]); i++) {
      if (!strcmp(user_in, builtins[i])) {
        printf("Found command %s", builtins[i]);
        found = true;
        break;
      }
    }

    if (!found) {
      printf("Didn't find command\n");
    }
  }

  return 0;
}

Кроме того, относительно вашей функции init_shell: вы проверяете, является ли argc больше 1, но это только гарантирует, что определено argv[1];это не гарантирует, что argv[2] определен.(Помните, argc - это размер массива argv, где первый элемент - это имя выполняемой программы).Вы должны убедиться, что argc равен по крайней мере 3, прежде чем проверять наличие флага подсказки в том виде, в каком вы находитесь.

Это может быть излишним для вашего варианта использования, но рассмотрите возможность использования функции getopt для полученияПользовательское значение подсказки от пользователя.См. http://man7.org/linux/man-pages/man3/getopt.3.html для документации относительно этого метода.

...