2012-11-27 31 views
2

我正在通过“The C Programming Language”(K & R)的方式工作,并做了一个练习。练习是打印空格,制表符和换行符的数目,直到EOF。太好了,那是有效的。但是,我开始变得聪明起来,并添加了下面显示的实际上称为“空格”或“制表符”或“换行符”的printf()。它应该打印,因为我输入,但是,它只有似乎运行一次我打回车。使用getchar()while循环;但是,结果有点奇怪

代码:

#include <stdio.h> 

int main(int argc, const char * argv[]) 
{ 

    int c, nb, nt, nl; 

    nb = nt = nl = 0; 

    while ((c = getchar()) != EOF) { 
     if (c == ' ') { 
      nb += 1; 
      printf("Space\n"); 
     } 
     if (c == '\t') { 
      nt += 1; 
      printf("Tab\n"); 
     } 
     if (c == '\n') { 
      nl += 1; 
      printf("New Line\n"); 
     } 

    } 

    printf("%d spaces, %d tabs, %d newlines",nb,nt,nl); 

    return 0; 
} 

输出:

a b 
Space 
New Line 
c d e 
Space 
Space 
New Line 
f g 
Tab 
New Line 
3 spaces, 1 tabs, 3 newlines 

我期望看到什么更多的东西是这样的:

a Spaceb 
New Line 
c Spaced Spacee 
New Line 
f tabg 
New Line 
3 spaces, 1 tabs, 3 newlines 

那么,为什么我得到了我得到,而不是我所期望的?

而且,是的,如果我真的关心,我会根据这个值做出'空格'''选项卡''和'换行符'复数,而不是基于值,但是,这只是一个练习。 ;)

+4

'stdin'通常是行缓冲的,因此终端在输入换行符之前不会将输入发送到您的程序。 –

+0

谢谢..我认为这可能会发生......但是,如何让stdin不被行缓冲?所以我可以实时处理击键? – DrDavid

回答

1

您的终端处于规范模式 - 字符累积到行尾。只有这样他们才会发送给用户(一个接一个)。

如果您想要立即响应,您必须将终端切换到原始模式。

PS。或多或少,如下所示:

struct termios t; 

tcgetattr (0, &t); 

t.c_lflag &= ~ICANON; 
t.c_cc [VMIN] = 1; 
t.c_cc [VTIME] = 0; 

tcsetattr (0, TCSANOW, &t); 
+0

在Xcode中,如何做到这一点? – DrDavid

+0

不得不添加:#include 但是,否则,按预期工作。谢谢! – DrDavid