簡體   English   中英

使用strcmp和char * arr []的分段錯誤

[英]Segmentation fault using strcmp and char *arr[]

我正在創建一個外殼,並且我已經有一段時間沒有使用C了。 我已經正確初始化了外殼,但是當我嘗試將用戶輸入與字符串數組進行比較時,卻遇到了段錯誤。 我計划在for循環中添加casce語句,以在用戶調用每個進程后啟動每個進程。 由於我一直試圖弄清楚如何使用戶輸入與字符串數組中的值匹配,所以我沒有包括這些內容。 在調試下,由於它是正確的指針,因此我僅接收該類生成的builtins [j]值的第一個字符。 但是我被困住了,並且可以使用一些想法來解釋為什么當我輸入“ exit”時它沒有返回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);
}

這里的問題是,您正在將用戶輸入寫入緩沖區,該緩沖區的大小不足以容納空終止符以外的任何內容。

char user_in[] = "";

上一行告訴C編譯器,您只需要足夠的空間來存儲[ '\\0' ] (這是一個字節)。 C編譯器不知道您以后可能會向該緩沖區寫入100字節的字符串。

當您寫入緩沖區時,用戶的輸入將溢出,並將覆蓋堆棧中的其他值。 由於堆棧中的其他值是指針,因此會發生段錯誤,因為您正在將字符值寫入這些字節,但是將它們解釋為char指針。

您正在正確地將允許用戶輸入的大小限制為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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM