2016-12-15 57 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'它只是爲了解釋新的字符。

相關問題