作者reefuj (重要的是心 心阿)
看板EE_DSnP
標題Re: [問題] 一個小問題...
時間Sun Nov 11 05:01:04 2007
在
http://topic.csdn.net/t/20050217/13/3787397.html
對我來說 裡面的程式比這個例子容易了解cin.get()和cin.getline()的差別
其實在沒有特別設定額外的delim狀況下
cin 接受的 delim 是 換行字元 和 空白字元
cin.get() 接受的 delim 只有換行字元
cin.getline() 接受的 delim 只有換行字元
cin.get(char* s, streamsize n, char delim )是一個一個讀入每個字元, 並
且把處理字元的pointer留在現在的delim上面
cin.getline(char* s, streamsize n, char delim )是一次讀入一串字元陣列,
從s處切到delim出現前一個, 並且把處理字元的pointer切到第一個
delim之後的第一個字元(這樣就做到直接忽略delim的效果)
1 #include <iostream>
2 using namespace std;
3 int main()
4 {
5 char myarray1[30];
6 cout<<"put your string 1:"<<"\n";
7 cin.getline(myarray1,30,'*'); <--輸入 1111*2222換行
8 cout<<myarray1<<"\n"; <--輸出 1111換行 (pointer在哪?)
9 char ch1;
10 cin.get(ch1);
11 cout<<ch1<<"\n"; <--輸出 2換行 (pointer在哪?)
12
13 char myarray2[30];
14 cout<<"put your string 2:"<<"\n";
15 cin.get(myarray2,30,'*'); <--繼續輸入1111*2222換行
16 cout<<myarray2<<"\n"; <--輸出 222換行1111換行 (why?)
17 char ch2;
18 cin.get(ch2);
19 cout<<ch2<<"\n"; <--輸出*
20 return 0;
21 }
螢幕看到的結果最後的輸出是
put your string 1:
1111*2222 <--line 7
1111 <--line 8
2 <--line 11
put your string 2:
1111*2222 <--line 15
222 <--line 16
1111 <--line 16
* <--line 19
大家可以比對看看前面的程式部份
我想前面兩個輸出大家都容易接受
後面兩個只要想清楚你灌進去的cin只有一個就能夠明白
其實你的輸入就是
1111*2222(換行)1111*2222
而這隻程式特別定義delim是 '*' 所以(換行)不是delim了 只是一個ASCII代碼
-------上面是教學-------我是分隔線我是分隔線-------下面是回答問題--------
以下是針對fig05_11.cpp討論
我的解釋是 你的^z呢 其實你把它的功能當作要cin.get()去處理目前手上有
的字元時就說的通了 (有點類似換行, 但是他是一個沒有ASCII碼的按鍵組合, 換行有)
狀況一
輸入 "a (換行) ^z" 會得到A:1
解釋: 因為(換行)按下去的時候, cin.get()會開始處理現在的字元串流,
所以A:0 -> A:1
此時pointer停在
(換行) <--(之前打成a....sorry)
但是這時候又遇到^z, 他要cin.get()處理在現在的字元串流
(想移動pointer到下一個位置, 可是已經在串流結尾, 回傳EOF)
這就是停下來的原因
狀況二
輸入 "a ^z" 不會停
解釋: 因為這一個^z會要cin.get處理a,
下一個^z停下來的原因同狀況一的停止原因
所以結論是....其實這個程式設計的停止條件只有一個
就是那個字元串流空掉了 就該休息了....
而不是要你們打出EOF這個ASCII碼就會停掉....
我不太確定EOF用按鍵打不打的出來...
※ 引述《jimjjj ((鯰川彥)~飛呀)》之銘言:
: ※ 引述《oker (oker)》之銘言:
: fig05_11.cpp的程式
: 當我輸入a 再輸入^z會得到A:1
: 當我輸入abc 也會得到A:1 B:1 C:1
: 可是當我輸入a^z 卻甚麼也不會得到(當然 我再輸入^z會得到A:1)
: cin.get()一次能接收一個字元..在這個.cpp中用while去跑
: 為什麼輸入a^z不會得到A:1????
: ~~~~~~~~~~~~~~~~~
: 因為是cin.get()的特性吧~在這裡是一次接收一個至char,所以當讀入
: a^z後~先將a存入~而^z就留在輸入佇列中~
: 所以再一次的cin.get()接收^z會顯示default訊息
: 而或許也正是因為^z只是模擬所謂的檔案結尾~
: 所以有些編譯程式本來就只有必須在第一個字就^z然後緊接按enter才有用
: 也大概就是^z在下一次當做一種符號的原因吧~
: 此int 值是26~ // 是ascII碼的值吧?
: 一個小程式可以驗證cin.get()的特性
: int main (){
: char k;
: k=cin.get(); // 執行時一口氣輸入abc三個字
: cout<<k<<endl; //緊接著顯示a
: k=cin.get();
: cout<<k<<endl; //下一行顯示b
: k=cin.get();
: cout<<k<<endl; //下下一行顯示c
: system("pause");
: }
: ~~~~~~~~~~~~~~~~~
: 推 ric2k1:助教, 請幫忙回答, 我手邊沒有課本. 11/09 17:17
: 推 nicksxz:根據我實驗的結果 如果^z不是放一行的第一個位置的話 11/09 18:43
: → nicksxz:cin.get()會把它當成data 所以迴圈還沒結束 照理說應該 11/09 18:45
: → nicksxz:可以看到default的錯誤訊息 把grade印出來會看到4或26 11/09 18:46
: → nicksxz:真是有趣的發現! 11/09 18:51
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.112.42.185
1F:→ reefuj: ◆ 這一篇文章值 278 銀 11/11 05:01
2F:推 timrau:EOF在Windows是Ctrl-Z 在Linux是Ctrl-D 11/11 10:45
※ 編輯: reefuj 來自: 140.112.231.25 (11/11 15:37)