2017-08-09 40 views
2

我正在寫一個程序,在Linux終端上覆制輸入逐字輸出。代碼如下(來自Dennis Ritchie的C書)延遲輸出到EOF而不是換行

#include <stdio.h> 
/* copy input to output; 2nd version*/ 

main() 
{ 
    int c; 
    while ((c = getchar()) != EOF) 
     putchar(c); 
} 

該程序及其執行正常工作。但我想稍作修改。

輸出顯示在每個新行字符的終端上(當我按下Enter鍵時)。我想延遲輸出,直到按信號結束文件,按Ctrl + D。爲了延遲我在終端上的輸出,我必須對該程序進行哪些修改。

示例輸出我得到如下:

我希望得到
abcd (enter) 
abcd 
llefn;elnf(enter) 
llefn;elnf 
(ctrl+d) 

輸出示例如下:

abcd(enter) 
llefn;elnf(ctrl+d) 
abcd 
llefn;elnf 
+2

將字符放入緩衝區並顯示整個緩衝區和結束。沒有其他選項AFAIK –

+1

不需要更改程序的修復就是將輸入寫入文本文件,然後將其作爲輸入重定向到您的程序。 'a.out

+0

@Meehm是的,它沒有任何額外的空間工作正常,但有可能使用終端本身做的東西? – hanugm

回答

1

如前所述in the comments:把字符到緩衝區和顯示整個緩衝區末尾:

#include <stdio.h> 

#define BUF_SIZE 1024 

int main() 
{ 
     char str[BUF_SIZE]; // the buffer 
     int c, i = 0; 

     while (i < BUF_SIZE-1 && (c = getchar()) != EOF) 
     str[i++] = (char) c; 

     str[i] = '\0'; 

     printf("%s\n", str); // display the contents of the buffer 
} 
+0

不要寫簡單的'main()';它應該是最小的int main(),最好是int main(void)。這是這個千年所有標準的要求。 –

+1

@JonathanLeffler雖然OP正在讀一本書,但是從上個千年開始...... –

+0

@JonathanLeffler right,編輯。 –

2

您需要存儲這些ch字符的緩衝區,控制索引你在哪裏寫,當你收到EOF只是通過printf打印該緩衝區。

如果你不能解決這個問題,你可以在這裏激發

#include <stdio.h> 

#define BUFFER_SIZE 1024 

int main() 
{ 
    int c, i = 0; 
    char buffer[BUFFER_SIZE]; 

    while ((c = getchar()) != EOF) 
    { 
     if (i < BUFFER_SIZE - 1) 
     { 
      buffer[i] = c; 
      i++; 
     } 
     else 
     { 
      buffer[BUFFER_SIZE - 1] = '\0'; 
      printf("%s", buffer); 
      i = 0; 
     } 
    } 

    buffer[i] = '\0'; 
    printf("%s", buffer); 

    return 0; 
} 
+0

只要'c'不是0就可以正常工作。對於OP可能沒問題。 – chux

+0

此代碼還會每1023個字節輸出一個額外的'\ n',並在最後一個額外的一個。 – chqrlie

1

您可以用setvbuf(3)設置緩衝區stdout

#include <stdio.h> 
main() 
{ 
     int c; 
     char buf[BUFSIZ]; 
     setvbuf(stdout,buf,_IOFBF,BUFSIZ); 
     while ((c=getchar())!=EOF) 
       putchar(c); 
} 

這裏的關鍵是使用_IOFBF常數指定的完全緩衝模式。 緩衝器的大小被設置爲BUFSIZ通常等於8192

如由Jonathan萊弗勒緩衝器的大小有限的評論被正確指出可能導致程序突然吐出其內容錯亂的終端。爲了避免這種情況,可以跟蹤緩衝區的使用情況,並在緩衝區填滿時擴展其大小。

+1

沒關係,如果文件小於緩衝區大小。文件有時很大。 –

+1

我猜世界可能已經改變了。通常,BUFSIZ通常是512.即使是8192也不是那麼大,儘管它比我想象的要大得多。 –

+0

@JonathanLeffler自1996年以來,GNU/linux中的BUFSIZ是8192.在大多數情況下,應該足夠用於來自終端的交互式輸入。我同意,要正確實現規範,我們需要動態增長緩衝區。 –

2

一個簡單的,儘管草率和局部解決方案是配置stdout與大量緩衝器全緩衝:

#include <stdio.h> 

int main(void) { 
    int c; 

    setvbuf(stdout, NULL, _IOFBF, 32767); 
    while ((c = getchar()) != EOF) { 
     putchar(c); 
    } 
    return 0; 
} 

注:

  • 在一個32位或64位系統,則可能會使緩衝區變得非常大。
  • 通過NULLsetvbuf可以讓它爲malloc()分配緩衝區。
+0

你可以從一個很大的'size_t'值開始,除以2直到成功:D –

+0

@AnttiHaapala:是的,我可以寫'for(size_t size =〜(size_t)0 >> 1; size; size >> = 1){if(!setvbuf(stdout,NULL,_IOFBF,size)break;}'但這對於OP的技能水平來說太神祕了 – chqrlie

+0

如果你不知道你需要多大的緩衝區,但需要編程有效嗎?分配字節數量聽起來效率不高。:-) –