2016-08-20 2 views
0

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

  1. Перенаправление stdout в файл
  2. Перенаправление stderr в файл
  3. Перенаправление stdin в файл
  4. Read 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 
+0

1) 'getline' не является стандартной функцией C, но POSIX 2) Не предупреждайте предупреждения без необходимости. Добавьте 'return', функция вернет значение в любом случае! 3) 'char * path_array' является указателем на' char', а не массивом, и меньше может не указывать на ** массивы ** 'char'. 4) TL; DR, предоставить [mcve] и использовать отладчик. – Olaf

+0

Почему 'fork()'? – alk

+0

@alk это будет демон. В целях отладки я прокомментировал части демона. –

ответ

1

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

Смежные вопросы