简体   繁体   English

使用C的getline()时出现奇怪的行为

[英]Strange behavior while using C's getline()

I have encountered some strange behavior in the getline function while writing a small c program. 在编写一个小型C程序时,我在getline函数中遇到了一些奇怪的行为。 What I want to do: 我想做的事:

  1. Redirect stdout to a file stdout重定向到文件
  2. Redirect stderr to a file stderr重定向到文件
  3. Redirect stdin to a file stdin重定向到文件
  4. Read stdin line by line into an array of strings ( char *path_array ) stdin逐行读入字符串数组( char *path_array
  5. Print the output 打印输出

Now, when I run the program, the output looks like this: 现在,当我运行程序时,输出如下所示:

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: 

At the end of this output, below each retrieving line from array , there should be the corresponding string from the array. 在此输出的末尾,在retrieving line from array每个retrieving line from array之下,应该有retrieving line from array的相应字符串。 As you can see, the array is filled with empty strings. 如您所见,该数组填充有空字符串。

Using Clion's debug mode, I found out why this is the case: 使用Clion的调试模式,我发现了为什么会这样:

In the first for loop, every array-entry gets filled with the current line . 在第一个for循环中,每个数组条目都被当前line填充。 So instead of 所以代替

path_array[0] = line1

path_array[1] = line2

path_array[3] = line3 ... path_array[3] = line3 ...

it goes 它去

path_array[0] = line1

path_array[0] = line2, path_array[1] = line2

path_array[0] = line3, path_array[1] = line3, path_array[2] = line3 ... path_array[0] = line3, path_array[1] = line3, path_array[2] = line3 ...

Why is this the case? 为什么会这样呢? And how do I stop this from happening? 我该如何阻止这种情况的发生?

Here is the C code: 这是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

On the first call line is null so a new buffer is allocated. 在第一个调用行上为null,因此分配了新的缓冲区。 After that, line is not null so the same buffer is used. 之后,line不为null,因此使用相同的缓冲区。 Your array is full of pointers to the same buffer. 您的数组充满了指向相同缓冲区的指针。

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

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