我在将字符串插入C中的数组时遇到了麻烦

时间:2010-11-01 07:03:35

标签: c string

我无法捕捉到我在错误地将字符串插入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行:* /

3 个答案:

答案 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的内容复制到该新字符串中。