I';我在C语言中将字符串插入数组时遇到了麻烦
在C语言中将字符串插入数组时,我很难理解我做错了什么。下面是代码。printf行告诉我,我确实在读取正确的数据——但是在我将每一行数据粘贴到一个数组中之后——我然后检查它,发现数组的每个元素都填充了放入数组的最后一行 //代码片段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
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标准没有强制要求它),那么这种可能性很小