[英]While Function and cin in C++
自從我開始閱讀 Stroustrup 的書《編程原則和實踐》以來已經有幾天了。 他的語法重復檢測代碼如下,
string previous = " ";
string current;
while (cin >> current){
if (previous == current)
cout << "repeated word:" << current << "\n";
previous = current;
}
雖然他解釋了while語句,但我還是不太明白用while和cin組合如何分析整個句子。 如果它逐字逐句地獲取句子,那么究竟是什么決定了這一點。 例如,為什么不只停留在第一個單詞。
我正在回答,因為根據您的評論,您的問題似乎與其他答案所解決的問題不同。
std::istream
是一個流; C++ 中使用的順序輸入形式。 (它也可以用於某些形式的非順序輸入,但這是一個高級功能,使用起來很棘手,這里我們不需要關心。)順序輸入或流的重要方面是它從其源中提取數據,一旦提取出數據,就不再可以訪問了。 從邏輯上講,它可以被認為是文件中數據的位置標記; 每次提取一個字符時,位置標記都會前進,並且總是在位置標記處提取。 所以當你寫:
std::string dest;
std::cin >> dest;
>>
運算符(它只不過是一個具有特殊名稱的函數,您將在本書后面看到)首先提取字符,直到找到不是空格的字符; 然后提取字符,直到找到一個空白字符,然后將提取的每個字符放入dest
。 如果沒有更多字符要提取,它也會停止,這種情況稱為文件結尾。 如果在將任何字符放入dest
之前發生這種情況,則輸入將失敗; 這個失敗將被記錄在流中,並且將在您在需要真或假的上下文中使用流時使用:除非流失敗,否則流為真。
但要保留的重點是流永遠不會兩次提取相同的字符。 如果您想更好地了解這一點,該流具有一些低級函數,可以讓您逐個字符地提取數據。 您可能想嘗試:
char ch;
while ( std::cin.get( ch ) ) {
std::cout << ch << std::endl;
}
std::istream::get
是一種非常非常低級的輸入,它總是只提取一個字符,而不會跳過空格或任何東西。 >>
所做的就是調用這個函數,直到它完成它的任務。 它有點復雜; 特別是, >>
通常直到將一個字符看得太遠才能知道它是否已完成,因此有一種方法可以查看下一個字符而不提取它,並且可以將您提取的最后一個字符推回前面的流,所以你可以再次閱讀。 並且有管理錯誤狀態的方法。 (假設您將>>
轉換為int
,但要讀取的下一個字符是“abc”。)但目前,您不必擔心所有這些。 目前,請記住,一旦讀取了一個字符,它就消失了,並且再也無法讀取。
答案很簡單。
while (cin >> current)
讀取輸入,直到里面沒有任何東西。 標准重載operator>>
跳過空格然后讀取所有內容,直到遇到另一個空格字符或到達輸入的末尾。 由於它在while
循環內,它將在循環的每次迭代中被調用。 這就是為什么句子被分成單詞的原因。
嘗試將其視為算法:
While the text isn t complete
read a word
if this word is like the previous one
there s a repeated word
store this word for next iteration
while (cin >> current)
會一個接一個地發送,直到 cin 為空。
簡單地說,直到有沒有離開它會讀單詞! 一旦達到了輸入的結束,或者非字符串遇到(好吧,祝你好運),錯誤標志被設置在流。 cin >> current
的計算結果為cin
,這反過來又可以轉化為布爾false
當錯誤標志。 由於您使用的cin >> current
作為循環條件,這結束循環。
cin
是istream
模板類的一個實例。 operator >>
作用於此 istream 實例以將輸入加載到數據中並返回對此istream
的引用。 然后通過調用cin::operator void*()
來測試它,該調用調用fail()
函數來測試操作是否成功。 這就是為什么你可以在 while 條件下使用這個操作
while ( cin >> current)
{
//...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.