我无法捕捉到我在错误地将字符串插入C中的数组中。下面是代码。 printf行告诉我,我确实正在读取正确的数据 - 但是在我将每行数据粘贴到数组之后 - 然后检查它以发现数组的每个元素都填充了放入数组的最后一行
//代码段
char outbuf[BUFFER_LEN];
int std_out_count = 0;
char *std_out_lines[BUFFER_LEN]; /* Array to hold STDOUT */
while ((i = read(stdout_pipe_fds[0], outbuf, BUFFER_LEN - 1)) > 0) {
outbuf[i] = '\0';
char temp[BUFFER_LEN];
printf("PARENT read from stdout: %s\n", outbuf);
strcpy(temp, outbuf);
std_out_lines[std_out_count] = temp;
std_out_count++;
}
printf("STDOUT_COUNT: %i\n", std_out_count); /* Print out elements of array to make sure they're correct */
int idx;
for(idx = 0; idx < std_out_count; idx++) {
printf("STDOUT[%i]: %s\n", idx, std_out_lines[idx]);
}
//我可以通过此输出看到我正在读取正确的值
/ * PARENT从stdout读取:STDOUT =:这是第0行:
PARENT从stdout读取:STDOUT =:这是第1行:
PARENT从stdout读取:STDOUT =:这是第2行:* /
//但是当我检查数组的元素时 - 每个元素都用最后一行读取;(
/ * STDOUT_COUNT:3 STDOUT [0]:STDOUT =:这是第2行:
STDOUT [1]:STDOUT =:这是第2行:
STDOUT [2]:STDOUT =:这是第2行:* /
答案 0 :(得分:3)
这一行:
char *std_out_lines[BUFFER_LEN];
分配一个字符指针的数组,但不为实际数据本身分配任何空间。
稍后,当你这样做时:
char temp[BUFFER_LEN];
printf("PARENT read from stdout: %s\n", outbuf);
strcpy(temp, outbuf);
std_out_lines[std_out_count] = temp;
你实际上覆盖了每个新行的相同的内存,并将其(不变的)地址存储到下一个字符指针中。char temp[BUFFER_LEN];
没有给你一个新的数据区。
这就是为什么它似乎有效。但是,当temp
超出范围时,我不会建议您尝试检查数组指向的任何行。这是未定义的行为。它似乎对你有用,但我保证这纯粹是偶然的: - )
您可能希望查看的是复制字符串,以便每个数组元素都有自己的副本。替换:
std_out_lines[std_out_count] = temp;
使用:
std_out_lines[std_out_count] = strdup(temp);
或者,完全抛弃temp
并使用:
std_out_lines[std_out_count] = strdup(outbuf);
这会生成字符串的副本,并为您提供存储到数组中的地址,以便它们彼此分开。请记住,你最终应该释放那些记忆。
如果您的C实现没有拥有 strdup
(ISO标准没有强制要求),here's one I prepared earlier。
答案 1 :(得分:1)
您需要分配一些存储而不是使用临时临时变量。
目前,每次循环时都会重复使用temp变量。
使用类似
的内容std_out_lines[i] = malloc(BUFFER_LEN);
// check for null here too, malloc can fail.
答案 2 :(得分:1)
您正在插入一个指向堆栈分配缓冲区'temp'的指针,该指针大部分时间都是相同的指针。
将您的while循环代码更改为:
outbuf[i] = '\0';
printf("PARENT read from stdout: %s\n", outbuf);
std_out_lines[std_out_count] = strdup(outbuf);
std_out_count++;
strdup()将为插入std_out_lines数组的字符串分配存储空间,并将outbuf的内容复制到该新字符串中。