簡體   English   中英

帶有一個輸入的 strcmp 的分段錯誤

[英]Segmentation Fault With Strcmp With One Input

我遇到了以下代碼的問題。

我有一個全局變量

char tokens[512][80];

連同代碼:

int main(int argc, char** argv) {
    char *input = malloc(sizeof(char) * 80);

    while (1) {
        printf("mini-shell>");
        fgets(input, 80, stdin);
        parse(input);

        if (strcmp(tokens[0], "cd") == 0) {
            cd();
        }
        else if (strcmp(tokens[0], "exit") == 0) {
            exit(1);
        }
    }
}

void parse(char str[]) {
    int index = 0;
    char* str_ptr = strtok(str, " ");

    while (str_ptr != NULL) {
        strcpy(tokens[index], str_ptr);
        str_ptr = strtok(NULL, " \0\r\n");
        //printf("%d\n", index);
        index = index + 1;
    }
}

我發現如果我為 stdin 輸入exit我會得到一個分段錯誤,但是如果我為 stdin 輸入cd ..我不會。 為什么會這樣?

我們不知道cd()函數的定義是什么,但是您可能希望在此程序中考慮許多事情。

首先,我認為為input緩沖區動態分配 80 字節內存沒有任何好處,因為您可以使用char input[80];在堆棧上輕松地自動分配char input[80]; - 這是免費且簡單的,完成后無需重新分配。

如果你這樣做,你可以用fgets(input, sizeof input, stdin)導出大小,如果你將輸入行的大小從 80 更改為其他數字,則只需更改一次:數組上的sizeof拉直接看尺寸。

您的parse()例程也需要一點幫助。 如圖所示通過extern聲明函數是一個非常好的主意,這樣當編譯器看到您在循環中調用函數時(就在fgets ),它就知道參數和返回類型。 否則它必須做出假設。

由於parse()將您從輸入中讀取的行分開,因此不需要將字符串復制到其他位置,因此您可以將tokens從多維數組轉換為簡單的指針數組。 當您通過該行運行strtok()以拆分參數時,您可以只存儲指針,知道它們將指向穩定數據,直到下一個fgets()

另外:您的代碼並不嚴格要求或使用它,但是在tokens列表的末尾添加一個NULL指針是一個非常好的主意:否則,調用者如何知道實際輸入了多少參數? 此代碼檢查用戶是否只輸入了一個空行。

我們還稍微改變了循環,因此strtok()只調用一次而不是兩次,包括注釋中提到的\\n

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

char *tokens[512];

extern void parse(char *str);

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

    while (1) {
        printf("mini-shell> "); fflush(stdout); // make sure user sees prompt
        fgets(input, sizeof input, stdin);
        parse(input);

        if (tokens[0] == NULL) continue; // user entered blank line

        if (strcmp(tokens[0], "cd") == 0) {
            cd();
        }
        else if (strcmp(tokens[0], "exit") == 0) {
            exit(1);
        }
    }
}

void parse(char *str) {
    int index = 0;

    char* str_ptr;

    while ( (str_ptr = strtok(str, " \n")) != NULL)
    {
        tokens[index++] = str_ptr;
        str = NULL; // for next strtok() loop
    }
    tokens[index] = NULL;
}

暫無
暫無

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

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