-4

基本的なシェルを開発しようとしています。そのシェルには、文字列を解析するための C 関数が必要です。私はCIが初めてなので、基本的な機能を開発しようとしましたが、セグメンテーション違反エラーが発生しました。私が欠けているものを教えてください。

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


void parse(char *msg);
int main()
{
    char *msg =  "This is a message";
    parse(msg);
}

void parse(char *msg){
    char *mm;
    mm = msg;

    char *tok;
    tok = strtok(mm," ");
    while(tok == NULL){
        tok = strtok(NULL," ");
            printf("%s \n",tok);
    }
}

エラー メッセージ (実行時)

Segmentation fault (core dumped)

前もって感謝します

4

6 に答える 6

5

msgが文字列リテラルを指しており、それを変更しようとしています。C では、文字列リテラルの変更は未定義の動作です(実際には、コンパイラはそれらを読み取り専用メモリに配置することがよくあります)。

修正するにはmsg、配列に変換します。

int main()
{
    char msg[] =  "This is a message";
    parse(msg);
}

whileまた、ループにはいくつかの問題があります。

1) 状態が逆です。
2) 2 番目のstrtok()呼び出しはprintf() .

void parse(char *msg){
    char *mm = msg;
    char *tok = strtok(mm, " ");
    while (tok) {
        printf("%s \n",tok);
        tok = strtok(NULL," ");
    }
}
于 2013-04-09T05:46:06.267 に答える
4

文字列リテラルを確実に変更することはできません。多くの場合、それらは読み取り専用です(あなたの場合、明らかに読み取り専用です)。文字列リテラルを変更しようとすると、未定義の動作が呼び出されます。これは常に悪いことです!

使用する:

int main(void)
{
    char msg[] = "This is a message";
    parse(msg);
}
于 2013-04-09T05:46:03.140 に答える
2

あなたの定義:

char *msg =  "This is a message";

msg変更できない定数文字列として作成します。しかし、strtokそれを変更します。

あなたはそれをに変更したいかもしれません

char *msg =  strdup("This is a message");

完了したら、ポインターを解放することを忘れないでください。

于 2013-04-09T05:47:28.113 に答える
1

おそらく代わりに

while(tok == NULL)

あなたが意味した

while(tok != NULL)

あるいは単に

while (tok) // <- because in C, conditions are always compared to 0

. ただし、セグメンテーション違反が発生するのは、渡された文字列を変更することです。これが、 const 以外のポインターをstrtok取る理由です( http://linux.die.net/man/3/strtokを参照)。したがって、変更できない文字列リテラルへのポインターを渡しているため、セグメンテーション違反が発生します (これは幸運です。運が悪ければ、このバグは QA をすり抜けて本番環境に移行する可能性もあります)。char

于 2013-04-09T05:46:21.170 に答える
1

それと一緒に行く.......

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


void parse(char *msg);
int main()
{
    char msg[] =  "This is a message";
    parse(msg);
}

void parse(char *msg){
    char *mm;
    mm = msg;

    char *tok;
    tok = strtok(mm," ");
    while(tok != NULL){
        printf("%s \n",tok);
    tok = strtok(NULL," ");
    }
}
于 2013-04-09T05:54:08.953 に答える
0

tok==NULL を tok!=NULL に変更してみてはいかがでしょうか。

于 2013-04-09T05:48:10.187 に答える