2016-12-15 28 views
3

我正在参加关于“C”的培训课程并遇到问题。这很难解释,所以我会发布代码。这是训练语法,所以不要问我为什么这样做。当这两个段块都在main()中运行时,第二个块的行为不像在main()中单独存在。我已经尝试了几个IDE认为它可能是一个错误。找不到为什么getchar()正在为第一次出现的换行符C

/* First Segment Block */ 
int c; 
printf("Type a letter: "); 
c = getchar(); 
printf("You typed '%c'\n",c); 

/* OR - outputs the same, to demonstrate putchar */ 

printf("You typed '"); 
putchar(c); 
printf("'\n\n"); 

/* Second Segment Block */ 
int a,b,d; 
printf("Type two letters: "); 
a = getchar(); 
b = getchar(); 
d = getchar(); 
printf("You typed '"); 
putchar(a); 
printf("' and '"); 
putchar(b); 
printf("' and '"); 
putchar(d); 
printf("'\n"); 

在第二部分块中,我添加了第三个变量来测试我的理论。当你输入所要求的两个字母时,第一个getchar()会选择一个新行,第二个getchar()会选取第一个字母。第三个getchar()拿起第二个字母。如果注释掉整个第一个段的块,那么它的行为是正确的,第一个getchar()获取第一个字母,第二个获取第二个getchar(),显示输出。

以下是两者一起运行时的输出。

Type a letter: k 
You typed (k) 
You typed 'k' 

Type two letters: lk 
You typed ' 
' and 'l' and 'k' 

RUN SUCCESSFUL (total time: 9s) 

当它们单独运行时,输出如下。

第一部分输出

Type a letter: k 
You typed (k) 
You typed 'k' 

RUN SUCCESSFUL (total time: 5s) 

第二部分输出。

Type two letters: rf 
You typed 'r' and 'f' and ' 
' 

RUN SUCCESSFUL (total time: 5s) 

第3个getchar()是一个换行符,这是预期的。

任何人都可以解释为什么当两个段运行在同一个主要(),行为是不同的,当运行分开?

谢谢你在前进, 丹尼尔N.(C语言初学者)

+1

回答完第一个提示后,您是否按回车?该换行符被下一个'getchar()'读取。 – Barmar

+2

当你输入第一个字母时,你也会碰到return,它显示为一个换行符。第二个'getchar()'读取换行符,然后读取两个字母(输入中有未读的换行符)。这是预期的行为。如果您键入'abc'并返回,那么事情就会像您期望的那样更加接近......除了额外的'getchar()'调用将会返回而无需您输入更多内容。 –

+1

换行符(''\ n'')也是'char' .. – chux

回答

3

在第一次提示时,输入像一个输入,让你的输入流中包含的字符'a', '\n'。第一个getchar调用读取a并在输入流中保留换行符。

针对第二个提示,键入bÇ输入,让你的输入流现在包含'\n', 'b', 'c', '\n'

你也许可以弄清楚从这里发生了什么 - 下一个getchar调用从输入流中读取换行符。

有几种方法可以解决这个问题。一个是测试你的输入,然后再试一次,如果它是一个新行:

do 
{ 
    a = getchar(); 
} while (a == '\n'); // or while(isspace(a)), if you want to reject 
         // any whitespace character. 

另一种是不使用getchar;相反,使用scanf%c转换说明和空白格式字符串:

scanf(" %c", &c); // you will need to change the types of your 
...     // variables from int to char for this. 
scanf(" %c", &a); 
scanf(" %c", &b); 
scanf(" %c", &c); 

格式字符串的前导空格告诉scanf忽略任何前导空格,这样你就不会拿起换行符。

+0

我正在进行的培训为它解释的每个细分创建了一个新文件,只要变量是唯一的,我只是将其添加到最后。我猜想“C”需要被告知如何处理每一个角色,即使当按下物理的“Enter”时,这是完全不可见的。 – DNadler

+1

@DNadler:换行符不可见;他们是一个像任何其他人物。他们没有与他们相关的字形,但他们确实影响显示。 –

0

两个 '空间' 和 '\ n(新行)' 是字符为好。所以,getchar()会获取你输入的每个字符。例如,如果您按'a(enter)b',它会读取a ='a',b ='\ n',d ='b'。

0

发生这种情况是因为您的终端是行缓冲的,所以它正在等待您按Enter键,然后将您键入的字符传递给您的程序任意。当您按下回车键时,您的程序将收到您键入的任何字符,,其中包括由Enter键生成的换行符(\n)。

事件的实际顺序是这样的:

  1. 你的程序将打印第一个提示。
  2. 你的程序调用getchar(),它试图从标准输入流中读取一个字符。由于该流当前为空,因此它会暂停您的程序,直到某些输入到达。
  3. 您会看到提示并按下一个键(例如,X)。由于您的终端具有线路缓冲功能,因此您的程序尚未看到它,因此仍处于暂停状态。
  4. 按回车。您的终端现在将您输入的字符(X\n)发送到您的程序。
  5. getchar()返回标准输入中可用于程序的第一个字符,即X
  6. 您的代码现在打印第二个提示,并再次调用getchar()getchar()看到还有一个字符(\n)仍在标准输入中等待,并立即返回。
+0

第一个响应的换行符是两个输出之间的空行,对吗?因此,缓冲区中应该没有任何内容等待第二个响应。它已经输出到屏幕 – DNadler

+0

我的坏...我没有考虑物理按键盘上的“Enter”键。 – DNadler

0

这是输入流的方式。 当第一个段正在运行并输入第一个字符时,按回车。它基本上被视为输入流中的字符本身。所以如果你输入'a'并按回车键,它就像输入流中的'a \ n'。 现在用getchar,你从输入流中读取一个字符到你的变量,这里是'a'。在给你'一个'时,输入流仍然是'\ n'。 下一次你做getchar时,你会得到'\ n'作为char。即使你输入新的字符,它将始终是第一流,即'\ nabc ....'

'\ n'它只是为了解释新的字符。

相关问题