简体   繁体   English

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

[英]I'm having trouble with inserting a string into an array in C

I'm having trouble catching what I'm doing wrong inserting strings into an array in C. Below is the code. 我无法捕获在C中将字符串插入到数组中的错误操作。下面是代码。 The printf lines show me that I am indeed reading the correct data -- but after I stick each line of data into an array -- I then inspect it to find that every element of the array is filled with the last line put into the array. printf行向我表明我确实在读取正确的数据-但是在将每行数据粘贴到一个数组中之后,我随后对其进行检查以发现该数组的每个元素都被放入该数组的最后一行填充了。

//Code snippet //代码段

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]);
}

// I can see by this output that I'm reading the correct values //通过此输出可以看到我正在读取正确的值

/* PARENT read from stdout: STDOUT = :this is line number 0: / *从标准输出读取的PARENT:STDOUT =:这是行号0:

PARENT read from stdout: STDOUT = :this is line number 1: 从stdout读取的PARENT:STDOUT =:这是行号1:

PARENT read from stdout: STDOUT = :this is line number 2: */ 从stdout读取的PARENT:STDOUT =:这是第2行:* /

// But when I inspect the elements of the array -- every element is filled with the last line read ;( //但是当我检查数组的元素时-每个元素都填充有最后一行读取的内容;(

/* STDOUT_COUNT: 3 STDOUT[0]: STDOUT = :this is line number 2: / * STDOUT_COUNT:3 STDOUT [0]:STDOUT =:这是行号2:

STDOUT[1]: STDOUT = :this is line number 2: STDOUT [1]:STDOUT =:这是第2行:

STDOUT[2]: STDOUT = :this is line number 2: */ STDOUT [2]:STDOUT =:这是第2行:* /

This line: 这行:

char *std_out_lines[BUFFER_LEN];

allocates an array of character pointers but does not allocate any space for the actual data itself. 分配字符指针数组,但不为实际数据本身分配任何空间。

Later on, when you do: 稍后,当您这样做时:

char temp[BUFFER_LEN];
printf("PARENT read from stdout: %s\n", outbuf);
strcpy(temp, outbuf);
std_out_lines[std_out_count] = temp;

you're actually overwriting the same piece of memory which each new line and storing its (unchanging) address into the next character pointer. 您实际上是在覆盖每一行的相同内存,并将其(不变)地址存储到下一个字符指针中。 char temp[BUFFER_LEN]; doesn't give you a new data area every time it executes. 不会在每次执行时为您提供新的数据区域。

That's why it appears to be working. 这就是为什么它似乎起作用的原因。 However, when temp goes out of scope, I wouldn't suggest trying to examine any of the lines pointed at by your array. 但是,当temp超出范围时,我不建议您尝试检查数组所指向的任何行。 It's undefined behaviour. 这是不确定的行为。 It seems to be working for you but I'll guarantee that's purely by accident :-) 看来对您有用,但我保证这完全是偶然的:-)

What you may want to look at is duplicating the string so that each array element has its own copy. 您可能要看的是复制字符串,以便每个数组元素都有自己的副本。 Replace: 更换:

std_out_lines[std_out_count] = temp;

with: 与:

std_out_lines[std_out_count] = strdup(temp);

or, just ditch temp altogether and use: 或者,完全放弃temp并使用:

std_out_lines[std_out_count] = strdup(outbuf);

This makes a copy of the string, and gives you the address of it for storing into the array, so that they're all separate from each other. 这将创建字符串的副本 ,并为您提供用于存储到数组中的字符串的地址,以使它们彼此分开。 Just remember that you should probably free that memory eventually. 请记住,您最终可能应该释放该内存。


On the off-chance that your C implementation doesn't have a strdup (it's not mandated by the ISO standard), here's one I prepared earlier . 在关闭的机会,你的C实现不具备 strdup (它不是由ISO标准规定的), 这里有一个我提前准备

You need to allocate some storage rather than use the temp temporary variable. 您需要分配一些存储空间,而不是使用temp临时变量。

At present you are re-using the temp variable each time round the loop. 目前,每次循环时您都在重用temp变量。

Use something like 使用类似

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

You are inserting a pointer to a stack allocated buffer 'temp', which most of the time will be the same pointer. 您将插入一个指向堆栈分配的缓冲区“ temp”的指针,大多数情况下,它们将是相同的指针。

Change your while loop code to: 将您的while循环代码更改为:

  outbuf[i] = '\0';
  printf("PARENT read from stdout: %s\n", outbuf);
  std_out_lines[std_out_count] = strdup(outbuf);
  std_out_count++;

strdup() will allocate storage for the string inserted into std_out_lines array and copy the contents of outbuf into that new string. strdup()将为插入std_out_lines数组的字符串分配存储空间,并将outbuf的内容复制到该新字符串中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM