Я столкнулся с каким-то странным поведением в функции getline
при написании небольшой c-программы. То, что я хочу сделать:Странное поведение при использовании C getline()
- Перенаправление
stdout
в файл - Перенаправление
stderr
в файл - Перенаправление
stdin
в файл - Read
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
, должна быть соответствующая строка из массива. Как вы можете видеть, массив заполняется пустыми строками.
Использование режима отладки Clion, я узнал, почему это так:
В первом 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 это будет демон. В целях отладки я прокомментировал части демона. –