I';我在C语言中将字符串插入数组时遇到了麻烦

I';我在C语言中将字符串插入数组时遇到了麻烦,c,string,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_p

在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]);
}
char突发[BUFFER_LEN];
int std_out_计数=0;
字符*标准输出线[缓冲区长度];/*用于保存标准输出的数组*/
而((i=读取(标准管道fds[0],突发,缓冲区长度-1))>0){
exputf[i]='\0';
字符温度[缓冲区长度];
printf(“从标准输出读取的父项:%s\n”,exputf);
strcpy(温度、温度);
标准输出线[标准输出计数]=温度;
标准输出计数++;
}
printf(“标准输出计数:%i\n”,标准输出计数);/*打印出数组的元素以确保它们是正确的*/
int-idx;
对于(idx=0;idx
//通过这个输出,我可以看出我读取的值是正确的

/* 从标准输出读取的父项:标准输出=:这是行号0:

从标准输出读取的父项:标准输出=:这是第1行:

从标准输出读取的父项:标准输出=:这是第2行:*/

//但是当我检查数组的元素时——每个元素都被最后读取的行填充;(

/* STDOUT_计数:3 标准输出[0]:标准输出=:这是第2行:

STDOUT[1]:STDOUT=:这是第2行:


STDOUT[2]:STDOUT=:这是行号2://

您需要分配一些存储,而不是使用temp临时变量

目前,每次循环都在使用temp变量

使用类似

std_out_lines[i] = malloc(BUFFER_LEN);
// check for null here too, malloc can fail.

您需要分配一些存储,而不是使用temp临时变量

目前,每次循环都在使用temp变量

使用类似

std_out_lines[i] = malloc(BUFFER_LEN);
// check for null here too, malloc can fail.

您正在插入一个指向堆栈分配的缓冲区“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_line数组中的字符串分配存储空间,并将extuf的内容复制到新字符串中。

您正在插入一个指向堆栈分配的缓冲区“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数组的字符串分配存储空间,并将EXBUF的内容复制到新字符串中。

此行:

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;
与:

或者,只需完全抛弃
temp
,然后使用:

std_out_lines[std_out_count] = strdup(outbuf);
这将创建字符串的副本,并为您提供存储到数组中的字符串地址,以便它们彼此独立。只要记住,你可能最终会释放那些记忆


如果您的C实现没有一个
strdup
(它不是ISO标准强制要求的),那么这一行:

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;
与:

或者,只需完全抛弃
temp
,然后使用:

std_out_lines[std_out_count] = strdup(outbuf);
这将创建字符串的副本,并为您提供存储到数组中的字符串地址,以便它们彼此独立。只要记住,你可能最终会释放那些记忆


如果您的C实现没有一个
strdup
(ISO标准没有强制要求它),那么这种可能性很小