我在编写一个小型的c程序时遇到了getline
函数中的一些奇怪的行为。我想要做的:使用C的getline时奇怪的行为()
- 重定向
stdout
到文件 - 重定向
stderr
到文件 - 重定向
stdin
到文件 - 读
stdin
一行一行到字符串数组(char *path_array
) - 打印输出
现在,当我运行该程序时,输出看起来像这样:
retrieving line of size 73.
line1 llllllllllllskdjflaksdlfkalskdddddddffffffffffffffffffffffffffffff
retrieving line of size 6.
line2
retrieving line of size 6.
line3
retrieving line of size 6.
line4
retrieving line of size 6.
line5
retrieving line of size 6.
line6
retrieving line of size 6.
line7
retrieving line of size 6.
line8
retrieving line of size 1.
retrieving line of size 13.
sdkfjlskdfos
retrieving line of size 9.
sldjflsd
retrieving line of size 9.
sdlfkjsd
retrieving line of size 11.
2222222222
retrieving line of size 11.
3333333333
retrieving line from array:
retrieving line from array:
retrieving line from array:
retrieving line from array:
retrieving line from array:
retrieving line from array:
retrieving line from array:
retrieving line from array:
retrieving line from array:
retrieving line from array:
retrieving line from array:
retrieving line from array:
retrieving line from array:
retrieving line from array:
在该输出结束时,每个retrieving line from array
下面,应该有从阵列对应的字符串。正如你所看到的,数组中填充了空字符串。
使用克利翁的调试模式下,我找到了原因是这样的话:
在第一for
循环,每个数组条目得到填补当前line
。因此,而不是
path_array[0] = line1
path_array[1] = line2
path_array[3] = line3
...
它去
path_array[0] = line1
path_array[0] = line2, path_array[1] = line2
path_array[0] = line3, path_array[1] = line3, path_array[2] = line3
...
为什么会出现这种情况?如何阻止这种情况发生?
这里是C代码:
#include <zconf.h>
#include <dirent.h>
#include <stdlib.h>
#include <fcntl.h>
#include <stdio.h>
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wmissing-noreturn"
int main(void) {
int out_log;
int err_log;
int conf_in;
pid_t pid = fork();
DIR *dir;
struct dirent *entry;
//for getline()
char *line = NULL;
size_t len = 0;
ssize_t read;
int array_size = 0;
// if (pid < 0) {
// exit(1);
// }
// else if (pid > 0) {
// exit(0);
// }
//
// if (setsid() <= 0) {
// exit(1);
// }
if (chdir("/") != 0) {
exit(1);
}
// if ((dir = opendir(".")) == NULL) {
// exit(1);
// }
//redicrect stdout
if (dup2(out_log = open("PATH_TO_OUT_FILE", O_WRONLY | O_TRUNC), 1) != 1) {
exit(1);
}
if (close(out_log) != 0) {
exit(1);
}
//redirect stderr
if (dup2(err_log = open("PATH_TO_ERR_FILE", O_WRONLY | O_TRUNC), 2) != 2) {
exit(1);
}
if (close(err_log) != 0) {
exit(1);
}
//redirect stdin
if (dup2(conf_in = open("PATH_TO_IN_FILE", O_RDONLY), 0) < 0) {
exit(1);
}
if (close(conf_in) != 0) {
exit(1);
}
while ((read = getline(&line, &len, stdin)) != -1) {
array_size++;
printf("retrieving line of size %zd.\n", read);
printf("%s\n", line);
}
rewind(stdin);
char *path_array[array_size];
for (int i = 0; i < array_size; i++) {
getline(&line, &len, stdin);
// HERE IS WHERE IT GOES WRONG
path_array[i] = line;
}
free(line);
for (int i = 0; i < array_size; i++) {
printf("\n\n\nretrieving line from array: %s\n", path_array[i]);
}
// while (1) {
// puts("test output");
// printf("%zd\n", read);
//
// fflush(stdout);
//
// sleep(1);
// }
}
#pragma clang diagnostic pop
1)'getline'不是标准的C函数,但POSIX 2)不需要提供警告。添加'return',函数无论如何都会返回一个值! 3)'char * path_array'是一个指向'char'的指针,而不是一个数组,不能指向** char **的数组**。 4)TL; DR,提供[mcve]并使用调试器。 – Olaf
为什么'fork()'? – alk
@alk它将成为一个守护进程。为了调试目的,我将守护程序部分注释掉了。 –