2016-10-28 19 views
-2

我试图在C中模拟tail命令,但是我遇到了问题。C - 从键盘读取(由Ctrl + D控​​制)

我需要从键盘读取一些行(STDIN)(我不在乎有多少行)。当按下Ctrl + d时,该读取将被中断。我已经完成了这个功能,但它不起作用。

int tail(int N) 
{ 
    int i, j, c; 
    char ** lines; 
    /* Char matrix dynamic declaration */ 
    lines=NULL; // Char matrix declaration 
    lines=malloc(N*sizeof(char *)); 
    for (i=0; i<N; i++){ 
     lines[i]=malloc(80 * sizeof(char)); 
    } 
    i=0; 
    while (true){ // I tried this loop, but doesn't work 
     /* This works. Lanes reading from the user's keyboard */ 
     if(i>=N){ 
      for(j=0; j<=N; j++){ 
       if (j<(N-1)) 
        lines[j]=lines[j+1]; 
      } 
      scanf(" %[^\n]", lines[N-1]); 
     }else{ 
      scanf(" %[^\n]", lines[i]); 
     } 
     i++; 
     /* ------------------------------------ */ 
     c=getchar(); // This doesn't work 
     if(c==EOF) 
     goto end; 
    } 
end: 
    for (i=0; i<N; i++){ 
     printf("%s\n", lines[i]); // Showing those lanes 
     free(lines[i]); // Free memory 
    }  
    free(lines); 
    lines = NULL; 

    return 0; 
} 

我的问题是关于读取用户的键盘行和读取CTRL + D在同一时间。当我启动这个函数时,它让我写了一些行,但是当我按下Ctrl + D时它没有检测到。我怎样才能做到这一点?

编辑:

我曾试图捕捉按Ctrl + d和新方法,现在我的程序结束,但我有一些问题。下面是新的代码:

int tail(int N) 
{ 
    int i, j, k, c; 
    char ** lines; 

    lines=NULL; 
    lines=malloc(N*sizeof(char *)); 
    for (i=0; i<N; i++){ 
     lines[i]=malloc(MAXLON * sizeof(char)); 
    } 
    i=0; 
    while (true){ 
     /* Read lines from keyboard. */ 
     if(i<N) 
      scanf(" %[^\n]", lines[i]); 
     else{ 
      for(j=0; j<N-1; j++){ 
       for(k=0; k<MAXLON; k++){ 
        lines[j][k]=lines[j+1][k];  
       } 
      } 
      scanf(" %[^\n]", lines[N-1]); 
     } 
     /* ------------------------------------ */ 
     if((c=getchar())==EOF) break; 
     else i++; 
    } 

    for (i=0; i<N; i++){ 
     printf("%s\n", lines[i]); 
     free(lines[i]); 
    } 
    free(lines); 
    lines= NULL; 

    return 0; 

} 

现在,我的程序从键盘捕捉N行,直到我按2次按Ctrl + d,但现在我的问题是:如果我写了5线,(有尾(3 )例如,其示出了过去的3线):

Line 1 
Line 2 
Line 3 
Line 4 
Line 5 
AND HERE I PRESS 2 TIMES CTRL+D 

功能将显示:

Line 4 
Line 5 
Line 5 

的哪些错误?该功能必须显示:

Line 3 
Line 4 
Line 5 

非常感谢!

+1

在有些情况下'goto'和标签是可以接受的情况。使用它们进行循环或循环控制不是那种情况之一。如果你想跳出一个循环,那么使用'break'语句。 –

+0

至于你的问题,当你按下文件结束键盘序列时,它通常必须在空行上。 –

+0

你好!我也尝试了休息,但没有奏效。当我从我的键盘上写了一行,然后按Enter键,然后按Ctrl + D,功能没有完成... –

回答

0

请参见下面的代码作为工作例如:

#include <stdio.h> 

int main(int argc, char* argvp[]) 
{ 
    char buf[1024]; 

    while(gets(buf)) 
    { 
     printf("Read: %s\n", buf); 
    } 
    if (ferror(stdin)) 
     puts("I/O error when reading"); 
    else if (feof(stdin)) 
     puts("End of file reached successfully"); 
} 

请注意,

  1. buf不应该被硬编码
  2. gets输入缓冲区的大小已被弃用,你应该使用其他的东西,如fgets
  3. END-OF-FILE不被识别在一条线的中间。它必须是第一线符号。它是如此的对我的RHEL 7.1,但可能是你的系统
  4. stdin不同应该与你的实际输入文件描述符被替换
+0

我已经使用你的代码(不一样,只是类似的东西)来尝试从STDIN中捕获Ctrl + d。但现在我有另一个错误。你能修改我编辑过的主要帖子吗? –

+0

您不需要调用getc()。您的第一个“Ctrl + D”结束您对“scanf”的调用,第二个“Ctrl + D”退出该功能。由于最后一个'scanf'被中止,因此'line [N-1]'的内容不会改变,您将始终看到最后一次输入的行两次。 – GMichael

+0

有什么我可以做的,以解决这个问题? –