我在編寫一個小型的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它將成爲一個守護進程。爲了調試目的,我將守護程序部分註釋掉了。 –