-1

私は C が初めてで、日付/時刻文字列を個別の変数に分割しようとしています。ただし、gdb のコードを 1 行ずつ実行すると機能しますが、ブレークポイントなしで正常に実行すると、エラーが発生し、その理由がわかりません。

以下はコードです:

char * dateTimeString = "2011/04/16 00:00";
char dateVar[11];
char timeVar[6];

if (splitTimeAndDateString(dateVar, timeVar, dateTimeString))
{
    exit(1);
}

printf("Date: %s\tTime: %s\n", dateVar, timeVar);

以下は機能です

int splitTimeAndDateString(char date[11], char time[6], char * dateString)
{
    char *token;
    token = strtok(dateString, " ");
    int i = 0;
    while (token != NULL)
    {
        if (i == 0)
        {
            strcpy(date, token);
        }
        else if (i == 1)
        {
            strcpy(time, token);
        }
        else
        {
            printf("Overrun date time string\n");
            return 1;
        }
        token = strtok(NULL, " ");
        i++;
    }
    return 0;
}

ご協力いただきありがとうございます。

4

1 に答える 1

9

このstrtok()関数は、解析する文字列を変更し、すべての区切り記号を\0ヌル記号に置き換えます。

読み取り: char * strtok ( char * str, const char * delimiters );

str
切り詰める C 文字列。
この文字列の内容が変更され、小さな文字列 (トークン) に分割されていることに注意してください。または、null ポインターを指定することもできます。この場合、関数は、関数への以前の呼び出しが正常に終了した場所のスキャンを続行します。

あなたのコードで:

 strtok(dateString, " "); 
           ^
           |  is a constant string literal 

dateString"2011/04/16 00:00"定数文字列リテラル を指しstrtok()、コードを使用して読み取り専用メモリに書き込もうとすることは違法であり、これによりセグメンテーション違反が発生しました。

理解するために、このリンクされた図の回答を読んでください: どのようにstrtok()機能しますか?

編集:

@: char * strtok ( char * str, const char * delimiters );指定されたコード例でstrは、定数文字列リテラルではなく、配列です。その宣言:

char str[] ="- This, a sample string.";

これstr[]は文字列で初期化され、その長さは割り当てられた文字列のサイズと同じです。str[]たとえばstr[i] = 'A'、有効な操作の内容を変更できます。

あなたのコードでは:

char * dateTimeString = "2011/04/16 00:00"; 

dateTimeString変更できない文字列リテラルへのポインタです。たとえば dateTimeString[i] = 'A'、今回は不正な操作です。

于 2013-07-09T15:08:35.347 に答える