0

history「履歴1」が入力されたときに最初のコマンドを実行することになっているコードは次のとおりです。

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

int main (int argc, char *argv[])
{
    int i=0; int j=0; int k=0;
    char inputString[100];
    char *result=NULL;
    char delims[] = " ";
    char historyArray[100][100] = {0};
    char *tokenArray[100][100] ;

    do
    {
        j = 0;
        printf("hshell>");
        gets(inputString);
        strcpy (historyArray[k], inputString);
        k++;

        // Break the string into parts
        result = strtok(inputString, delims);

        while (result!=NULL)
        {
            //result2 = result;
            strcpy(tokenArray[j], result);
            //puts(result);
            j++;
            result= strtok(NULL, delims);                  
            //puts(tokenArray[j]);     
        }
        //j = 0;
        puts(tokenArray[0]);
        puts(tokenArray[1]);

        if (strcmp(tokenArray[0], "exit") == 0)
        {
            return 0;
        }
        else if (strcmp(tokenArray[0], "history") ==  0)
        {
           if (j>1)
           {
              strcpy (result,historyArray[atoi(tokenArray[j-1])]);

           }
           else
           {
               //print history array
               for (i=0; i<k;i++)
                   printf("%i. %s\n", i+1, historyArray[i]);
           }
        }
        else
        {
          printf("Command not found\n");
        }
    }while (1);
}

ただし、クラッシュします。デバッグ中に、次の2つのことに気付きました。-配列(tokenArray)アドレスが範囲外である-アクセス違反(セグメンテーション違反)。下の画像でエラーを確認できます。

立入禁止で

セグメンテーション違反

私は何が欠けていますか?私は何が間違っているのですか?

4

2 に答える 2

1

セグメンテーション違反に対処している理由は、まだ割り当てられていないメモリに文字列をコピーしようとしているためです。あなたはとして定義resultし、char*それに割り当てNULLたばかりなので、文字列をそれにコピーしようとするのは間違っています:

char *result = NULL;
// ...
strcpy(result, historyArray[atoi(tokenArray[j-1])]);

resultを指すメモリを割り当てる必要があります。次にstrcpy、このメモリに文字列をコピーするために使用できます。を使用mallocして動的に割り当てるかresult、自動保存期間(つまり)を持つ一時変数として定義することができますchar result[100];


また、注意してください

char *tokenArray[100][100];

へのポインタの2次元配列を定義しますchar。ただし、この場合に実際に必要なのは文字列の配列であるため、*@cnicutarが指摘したように削除する必要があります。


そしてもう1つ注意してください:

strcpy(result,historyArray[atoi(tokenArray[j-1])]);

atoi失敗すると、配列の境界外で要素にアクセスしようとし、未定義の動作が発生するため、これを行うのは非常に危険です。したがって、次のようなことを行うことをお勧めします。

char tokenArray[100][100] = {0};

int index;
char indexString[100] = "8";
if (sscanf(indexString, "%d", &index) == 1)     // integer successfully retrieved
{
    strcpy(tokenArray[index], "some string");
    printf("%s", tokenArray[8]);
}
于 2013-02-24T13:36:39.020 に答える
1

あなたはおそらく、1つのトークンにそれぞれの文字char tokenArray[100][100];で作成100 tokensすることを意味しました。100

char *tokenArray[100][100]文字通り書くとtokenArray100、を含む配列の配列を意味します100 char *。ただしchar *、適切なアドレスが割り当てられていない場合、これらはそれぞれランダムなアドレスを指します。

char *の1つにアクセスできないアドレスが含まれているため、セグメンテーション違反エラーが発生します。

于 2013-02-24T14:42:45.617 に答える