1

私はCプログラミングにかなり慣れていないので、本当に理解できない問題を抱えています。ファイルから行を読み取り、各行を (文字列として) 配列に格納しようとしています。次に、その行で strtok を使用して、行から別の値を解析しています。strtokを使うとなぜか配列に入れている値が変わってしまいます。コードは以下のとおりです。

while(fgets(readLine, 100, inFile) != NULL) { 
    printf("j = %d\n", j);
    puts(readLine); 
    machineList[j] = readLine;
    puts(machineList[j]); //the value of machineList[j] at this point is equal
                          // to the current readLine 

    int i=0;

    day = strtok(readLine, " ,");

    puts(machineList[j]); //the value of machineList[j] at this point is no
                          //longer what it was at the previously noted point

    while(i<3) {
        day=strtok(NULL, " ,");
        i++;
    }
    dayList[j]=atoi(day);

    printf("Day is: %d\n\n", dayList[j] );  //these values come out as expected
    j++;

}

なぜこれが起こっているのか誰でも説明できますか?machineList[j]=readLine を再割り当てしているわけではないので、わかりません。したがって、readLine の値が変更されても、machineList[j] の値は変更されません。繰り返しますが、私は C を初めて使用するので、コードのセマンティクスがひどいものになる可能性があることを認識しています。何でも役に立ちます。ありがとう!

4

3 に答える 3

1

strtok区切り文字を null バイトに置き換えることで、元の文字列を変更します。

machineListは へのポインタの配列であると想定しているcharため、次のようになります。

machineList[j] = readLine;

...machineList[j]へのポインタを作成しますreadLine。次に、これ:

day = strtok(readLine, " ,");

...modifies 、これはそれを指しているためreadLine、これも変更します。machineList[j]代わりにコピーを作成する必要があります。

// allocate machineList[j]
strcpy(machineList[j], readLine);

コピーを作成しない場合、whileループが終了すると、machineList基本的にダングリング ポインターの配列になります。

于 2013-02-04T20:02:06.740 に答える
1

あなたの問題はここにあります

machineList[j] = readLine;

これはchar 文字列全体を にコピーするのではなくmachineList[i]、参照 (ポインタ、メモリ アドレス) のみを にコピーしreadLineます。したがって、 を変更してもreadLinemachineList[j]はこの変更された文字列を引き続き参照します。

文字列をコピーする場合は、次を使用しますstrcpy()

strcpy(machineList[j], readLine);

machineListメモリを割り当てていない場合は (コピーする前に)メモリを割り当てることを忘れないでください。

machineList[i] = malloc(strlen(readLine) + 1);

再開:

machineList[i] = malloc(strlen(readLine) + 1);
strcpy(machineList[j], readLine);

または、Arkadiy が指摘するようにstrdup()、1 つの文で割り当てとコピーを組み合わせるために使用します。

machineList[i] = strdup(readLine);

終了したら、メモリを解放することを忘れないでください。

free(machineList[i]); // For each i
于 2013-02-04T20:02:31.893 に答える
0
while(fgets(readLine, 100, inFile) != NULL) { 
    printf("j = %d\n", j);
    puts(readLine); 

ここで、 のアドレスreadLineが 0x1234abcd であるとします。

    machineList[j] = readLine;

現在、machineList[j]値が含まれています(したがって、ポイントします)0x1234abcd

    puts(machineList[j]); //the value of machineList[j] at this point is equal
                          // to the current readLine 

したがって、正しい答えが得られます。

    int i=0;

    day = strtok(readLine, " ,");

残念ながら、ここでは 0x1234abcd の値が変わります (readLine変更されるため)。0x1234abcdアドレスをmachineList[j]指すことを覚えておいてくださいreadLine

    puts(machineList[j]); //the value of machineList[j] at this point is no
                          //longer what it was at the previously noted point

:-(残念ながら、望ましくない結果が得られます。

代わりに、メモリに新しい文字列を作成し、データを複製してメモリへのポインタを返すstrdup()(STDC ではない) を使用できます。readLine

または、最初malloc()に文字列を ing してから、strcpy()

于 2013-02-04T20:09:20.190 に答える