Странное поведение при использовании C getline ()

c arrays string input file-io

70 просмотра

1 ответ

Я столкнулся с некоторым странным поведением в getlineфункции при написании небольшой программы на языке c. Что я хочу сделать:

  1. Перенаправить stdoutв файл
  2. Перенаправить stderrв файл
  3. Перенаправить stdinв файл
  4. Читайте stdinпострочно в массив строк ( char *path_array)
  5. Распечатать вывод

Теперь, когда я запускаю программу, вывод выглядит так:

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
Автор: de_dust Источник Размещён: 08.11.2019 11:22

Ответы (1)


1 плюс

На первой линии вызова пусто, поэтому выделен новый буфер. После этого строка не равна нулю, поэтому используется тот же буфер. Ваш массив полон указателей на тот же буфер.

Автор: stark Размещён: 20.08.2016 01:53
Вопросы из категории :
32x32