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都有相同的值,那就是数组的地址path,永远不会改变。

要实际获取path复制到的内容rawdata,您需要在rawdata[i]( malloc) 中为其分配内存,然后使用strcpy. 标准库中存在一个快捷方式,称为strdup

    ...

    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;

Finally, note that if you are putting a hard cap on the number of elements you are reading, make sure you don't violate it. That is, once i reaches 999, you shouldn't read more elements. Therefore:

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