2016-08-20 48 views
0

我在編寫一個小型的c程序時遇到了getline函數中的一些奇怪的行爲。我想要做的:使用C的getline時奇怪的行爲()

  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下面,應該有從陣列對應的字符串。正如你所看到的,數組中填充了空字符串。

使用克利翁的調試模式下,我找到了原因是這樣的話:

在第一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

第一次調用線是空,因此一個新的緩衝區分配。之後,行不爲空,所以使用相同的緩衝區。你的數組充滿了指向同一緩衝區的指針。