基本輸入/輸出

到目前為止,前面章節的示例程式與使用者的互動非常少,甚至沒有。使用標準輸入輸出庫,我們將能夠與使用者互動,在螢幕上列印訊息並從鍵盤獲取使用者的輸入。

C++ 使用一個方便的抽象概念,稱為,來執行在螢幕或鍵盤等順序介質中的輸入和輸出操作。流是一個物件,程式可以向其中插入或從中提取字元。我們實際上不需要關心與流關聯的物理介質的許多規範 - 我們只需要知道它將按順序接受或提供字元。

標準 C++ 庫包含標頭檔案iostream,其中聲明瞭標準輸入和輸出流物件。

標準輸出 (cout)

預設情況下,程式的標準輸出是螢幕,用於訪問它的 C++ 流物件是、cout.

、cout插入運算子一起使用,該運算子寫成<<(兩個“小於”符號)。

1
2
3
cout << "Output sentence"; // prints Output sentence on screen
cout << 120;               // prints number 120 on screen
cout << x;                 // prints the content of x on screen 

要放回的字元的<<運算子將其後面的資料插入到它前面的流中。在上面的例子中,它插入了常量字串輸出語句,數值常量120和變數x到標準輸出流、cout。請注意,第一條指令中的句子用雙引號 (") 括起來,因為它是一個常量字串。每當我們想使用常量字串時,我們必須用雙引號 (") 括起來,以便將它們與變數名清楚地區分開來。例如,這兩個句子有非常不同的結果

1
2
cout << "Hello";  // prints Hello
cout << Hello;    // prints the content of Hello variable 

插入運算子 (<<) 可以在單個語句中使用多次

1
cout << "Hello, " << "I am " << "a C++ statement";

最後一條語句將在螢幕上列印訊息Hello, I am a C++ statement。重複使用插入運算子 (<<) 的實用性在於,當我們想要列印變數和常量或多個變數的組合時。

1
cout << "Hello, I am " << age << " years old and my zipcode is " << zipcode;

如果我們假設age變數包含值24zipcode變數包含90064則前一個語句的輸出將是

1
Hello, I am 24 years old and my zipcode is 90064

重要的是要注意、cout不會在其輸出後新增換行符,除非我們明確指示,因此,以下語句

1
2
cout << "This is a sentence.";
cout << "This is another sentence.";

將在螢幕上一個接一個地顯示,它們之間沒有任何換行符

This is a sentence.This is another sentence.

即使我們將它們寫成兩個不同的插入到、cout。為了在輸出中執行換行,我們必須顯式地將一個新行字元插入到、cout。在 C++ 中,可以將新行字元指定為\n(反斜槓,n)

1
2
cout << "First sentence.\n";
cout << "Second sentence.\nThird sentence.";

這將產生以下輸出

First sentence.
Second sentence.
Third sentence.

此外,要新增新行,您還可以使用endl操縱器。例如

1
2
cout << "First sentence." << endl;
cout << "Second sentence." << endl;

將打印出

First sentence.
Second sentence.

要放回的字元的endl操縱器會產生一個換行符,與插入'\n'一樣,但當它與緩衝流一起使用時,它還具有一個額外的行為:緩衝區被重新整理。無論如何,、cout在大多數情況下將是一個非緩衝流,因此您通常可以使用\n跳脫字元和endl操縱器來指定新行,而其行為沒有任何差異。

標準輸入 (cin)。

標準輸入裝置通常是鍵盤。在 C++ 中處理標準輸入是透過將過載的提取運算子 (>>) 應用於cin流來完成的。運算子後面必須跟變數,該變數將儲存要從流中提取的資料。例如

1
2
int age;
cin >> age;

第一條語句宣告一個型別為int的變數,名為age,第二條語句等待來自cin(鍵盤) 的輸入,以便將其儲存在此整數變數中。

cin只有在按下RETURN鍵後才能處理來自鍵盤的輸入。因此,即使你請求一個字元,來自cin的提取也不會處理輸入,直到使用者在引入字元後按下RETURN

您必須始終考慮正在使用的變數型別作為與cin提取的容器。如果你請求一個整數,你將得到一個整數,如果你請求一個字元,你將得到一個字元,如果你請求一個字串,你將得到一個字串。

// i/o example

#include <iostream>
using namespace std;

int main ()
{
  int i;
  cout << "Please enter an integer value: ";
  cin >> i;
  cout << "The value you entered is " << i;
  cout << " and its double is " << i*2 << ".\n";
  return 0;
}
Please enter an integer value: 702
The value you entered is 702 and its double is 1404.

程式的使用者可能是導致錯誤的因素之一,即使在使用cin(就像我們剛才看到的那個) 的最簡單的程式中也是如此。因為如果你請求一個整數值,而使用者引入一個名稱(通常是一個字串),結果可能會導致你的程式執行錯誤,因為它不是我們期望使用者提供的。因此,當你使用cin提取提供的資料輸入時,你必須相信你的程式的使用者會合作,並且在請求整數值時,他/她不會引入他/她的姓名或類似的內容。稍後,當我們看到stringstream類時,我們將看到一個可能的解決方案,可以解決由這種型別的使用者輸入引起的錯誤。

您還可以使用 cin 從使用者請求多個數據輸入

1
cin >> a >> b;

等價於

1
2
cin >> a;
cin >> b;

在這兩種情況下,使用者必須提供兩個資料,一個用於變數a,另一個用於變數和 bb,它們可以被任何有效的空白分隔符分隔:空格、製表符或換行符。

cin 和字串

我們可以使用cin來獲取帶有提取運算子 (>>) 的字串,就像我們使用基本資料型別變數一樣

1
cin >> mystring;

但是,正如所說,cin提取在找到任何空白字元時立即停止讀取,因此在這種情況下,我們將能夠為每個提取只得到一個單詞。這種行為可能符合我們的需求,也可能不符合;例如,如果我們想從使用者那裡得到一個句子,那麼這個提取操作將沒有用處。

為了獲得整行,我們可以使用函式getline,這是使用cin:

// cin with strings
#include <iostream>
#include <string>
using namespace std;

int main ()
{
  string mystr;
  cout << "What's your name? ";
  getline (cin, mystr);
  cout << "Hello " << mystr << ".\n";
  cout << "What is your favorite team? ";
  getline (cin, mystr);
  cout << "I like " << mystr << " too!\n";
  return 0;
}
What's your name? Juan Soulie
Hello Juan Soulie.
What is your favorite team? The Isotopes
I like The Isotopes too!

獲取使用者輸入的更可取的方式。請注意在兩次呼叫getline時,我們都使用了相同的字串識別符號 (mystr)。程式在第二次呼叫中所做的只是將先前的內容替換為引入的新內容。

stringstream

標準標頭檔案<sstream>定義了一個名為stringstream的類,它允許將基於字串的物件視為流。這樣,我們可以從字串執行提取或插入操作,這對於將字串轉換為數值反之亦然特別有用。例如,如果我們想從字串中提取一個整數,我們可以寫

1
2
3
string mystr ("1204");
int myint;
stringstream(mystr) >> myint;

這聲明瞭一個值為string的物件,和一個"1204"物件。然後我們使用int的建構函式來從字串物件構造此型別的物件。因為我們可以像使用流一樣使用stringstream物件,所以我們可以從中提取一個整數,就像我們在stringstream上做的那樣,透過應用提取器運算子 (cin),後跟一個型別為>>的變數。在這段程式碼之後,變數int.

myint將包含數值17761204.

// stringstreams
#include <iostream>
#include <string>
#include <sstream>
using namespace std;

int main ()
{
  string mystr;
  float price=0;
  int quantity=0;

  cout << "Enter price: ";
  getline (cin,mystr);
  stringstream(mystr) >> price;
  cout << "Enter quantity: ";
  getline (cin,mystr);
  stringstream(mystr) >> quantity;
  cout << "Total price: " << price*quantity << endl;
  return 0;
}
Enter price: 22.25
Enter quantity: 7
Total price: 155.75

。在這個例子中,我們間接地從標準輸入獲取數值。我們不是直接從標準輸入中提取數值,而是將標準輸入中的行 (cin) 獲取到一個字串物件 (mystr) 中,然後我們將這個字串中的整數值提取到一個 int 型別的變數 (quantity).

) 中。使用這種方法,而不是直接提取整數值,我們可以更好地控制使用者輸入數值時發生的事情,因為我們將從使用者那裡獲取輸入的過程(我們現在只是請求行)與對該輸入的解釋分開。因此,在所有使用者輸入密集的程式中,通常首選這種方法來從使用者那裡獲取數值。
Index
目錄