2

popen() を使用して文字列の配列を作成しようとしていますが、配列内のすべてのインデックスが最後に返された文字列です。最終的には、すべてのファイルのディレクトリ リストを配列に取得しようとしています。

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

void main()
{
    FILE *fp;
    fp = popen("find ~/ -maxdepth 1 -type f", "r");
    if (fp == NULL) { printf("Failed to run command\n" ); exit; }

    char path[999];
    char* rawdata[999];
    int i = 0;

    while (fgets(path, sizeof(path)-1, fp) != NULL) {
        rawdata[i] = path;  // Shouldn't this assign every index
        i++;                // a different string ?
    }
    pclose(fp);

    /* Below, every index is the same string ? */
    printf("\n%s", rawdata[0]);
    printf("\n%s", rawdata[1]);
    printf("\n%s", rawdata[2]);
}
4

1 に答える 1

3
rawdata[i] = path;  // Shouldn't this assign every index a different string?

いいえpath。配列の名前である を保存しているため、配列の先頭へのポインターに減衰します。したがって、実際には、 のすべての要素はrawdata同じ値を持ち、それが array のアドレスであり、path変化することはありません。

pathにコピーされた の内容を実際に取得するには、 ( )rawdataでメモリを割り当ててから を使用する必要があります。このためのショートカットは、次の標準ライブラリに存在します。rawdata[i]mallocstrcpystrdup

    ...

    while (fgets(path, sizeof(path)-1, fp) != NULL) {
        rawdata[i] = strdup(path);
        if (rawdata[i] == NULL)
            goto exit_no_mem;
        i++;
    }
    n = i;

    ...

    /* in the end */
    for (i = 0; i < n; ++i)
        free(rawdata[i]);
    return EXIT_SUCCESS;
exit_no_mem:
    fprintf(stderr, "Out of memory\n");
    return EXIT_FAILURE;

最後に、読み取る要素の数に厳しい上限を設定している場合は、違反しないように注意してください。つまり、いったんiに到達999すると、それ以上要素を読み取ってはなりません。したがって:

    while (i < 999 && fgets(path, sizeof(path)-1, fp) != NULL)
于 2012-12-22T01:14:48.030 に答える