掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板2

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.26666

文字列をスプリットしたい
投稿者---kafuka(2006/04/21 11:57:25)


VB等のように文字列をデリミタでスプリットする関数をCで自作しようとして、以下SplitString()を作成しました。
VC++ 6.0 Releaseモードでコンパイルしたところ、実行時に落ちてしまいます。(Debugモードだと正しく結果を得る)
print文で落ちる位置を探したところ、コメント部で落ちていることが分かりましたが、何故落ちるのか、回避方法等が分かりません。
どうかアドバイスお願いします。
WinXP/VC++ 6.0

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

#define MAX_DATA    256
#define DATA    "aaaaaa,,bbbbbb,,,,cccccc,"
//#define DATA  ",,,ddd"

int SplitString(char*[], char*, char*);

int main(void)
{
    int i;
    int arycnt;
    char data[MAX_DATA];
    char* ary[MAX_DATA];

    memset(data, 0x00, sizeof(data));
    memset(ary, 'z', sizeof(ary));

    strcpy(data, DATA);
    arycnt = SplitString(ary, data, ",");

    printf("cnt=%d\n", arycnt);
    for (i = 0; i < arycnt; i++) {
        printf("%d:%s\n", i+1, ary[i]);
    }

    return 0;
}

int SplitString(char* array[], char* strdata, char* delimiter)
{
    int num = 0;
    int len;

    array[num] = strdata;
    len = strcspn(array[num], delimiter);
    while (array[num][len] != '\0') {
        array[num][len] = '\0';
        array[++num] = &array[num][len+1];
        // ↓ここで落ちる
        len = strcspn(array[num], delimiter);
    }
    num++;

    return num;
}



この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:文字列をスプリットしたい 26667 REE 2006/04/21 12:14:57
<子記事> Re:文字列をスプリットしたい 26668 nop 2006/04/21 12:30:51


No.26667

Re:文字列をスプリットしたい
投稿者---REE(2006/04/21 12:14:57)


> array[++num] = &array[num][len+1];
おそらく、これが未定義動作でしょう。
右辺のnumの評価と++numの動作の順序が保障されていません。
num++;
array[num] = &array[num-1][len+1];
などと置き換えてみましょう。



この投稿にコメントする

削除パスワード

No.26668

Re:文字列をスプリットしたい
投稿者---nop(2006/04/21 12:30:51)


> char* ary[MAX_DATA];
> memset(ary, 'z', sizeof(ary));

ポインタ配列の使い方が間違っています。
malloc()やcalloc()などで領域を確保しましょう。


この投稿にコメントする

削除パスワード

No.26669

Re:文字列をスプリットしたい
投稿者---REE(2006/04/21 13:28:17)


>> char* ary[MAX_DATA];
>> memset(ary, 'z', sizeof(ary));
>
>ポインタ配列の使い方が間違っています。
>malloc()やcalloc()などで領域を確保しましょう。

memsetは確かに無意味ですが、今回の例ではmallocなどは必要ないでしょう。



この投稿にコメントする

削除パスワード

No.26675

Re:文字列をスプリットしたい
投稿者---kafuka(2006/04/21 16:35:36)


REE様、nop様、回答ありがとうございます。

>> array[++num] = &array[num][len+1];
>おそらく、これが未定義動作でしょう。
>右辺のnumの評価と++numの動作の順序が保障されていません。
>num++;
>array[num] = &array[num-1][len+1];
>などと置き換えてみましょう。

ありがとうございました。
上記に修正することで意図する正しい結果を得ることができました。


>> char* ary[MAX_DATA];
>> memset(ary, 'z', sizeof(ary));
>
>ポインタ配列の使い方が間違っています。
>malloc()やcalloc()などで領域を確保しましょう。

ポインタの動きをデバッガで追いやすいように、意味のない統一された値で初期化していたのがそのままになっていました。
混乱させてしまって申し訳ありません。
#それにしても、ポインタを'z'で初期化ってなに考えてたんだろ。。。


本当にありがとうございました。


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧