2016-08-20 27 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

第一次调用线是空,因此一个新的缓冲区分配。之后,行不为空,所以使用相同的缓冲区。你的数组充满了指向同一缓冲区的指针。