整行輸入

常見

因為接下來的部分會提到「字串」,所以在正式開始之前這邊會需要先簡介一下字串的概念。

字串是什麼

字串,顧名思義就是「一串字」,這些字可以是:

  • 大小寫字母 (A ~ Za ~ z)
  • 數字
  • 符號

舉個例子,通常第一次寫程式時都寫過這段程式碼:

#include <bits/stdc++.h>
using namespace std;

int main() {
    cout << "Hello, world!";
    return 0;
}

事實上,Hello, world! 就是一個由字母、符號和空格組成的字串!

讀入整行字串

在上一章提到,可以利用 cin ,把數字讀入變數中,以下章節會用字串當例子。

這是一個字串輸入輸出的範例程式:

string s;
cin >> s;
cout << s << '\n';

程式執行過程中,一般只有輸入一個字串沒關係,但是如果輸入一段中間有空格分開的字串呢?會得到此輸出:

> APCS Guide
APCS

不難發現程式碼會略過空白後的字串,cin 函式也只會讀取 APCS 這個字串的輸入。

那要怎麼讓這兩個字串都被讀取到呢?可以利用 <string> 函式庫的 getline() 函式來解決這個問題。

getline

這個函式功能跟 cin 類似,但是可以讀取整行的字串,換句話說,它做的事情就是讀取到換行符號為止。

先來看看 getline() 的語法格式:

getline(輸入流, 變數);

在大部分情況下,輸入流都是 cin ,就是把輸入的字串存放到到變數所在的位子。

以下是一個使用 getline() 的範例程式:

string s;
getline(cin, s);
cout << s << endl;
> APCS Guide
APCS Guide

這樣就可以讀取到整行的字串了!

getline 與 cin 的混用

如果 getline() 前面有 cin 的話,可能會發生一些問題。

首先來看看這個範例程式:

int n;
string s;

// 先讀取一個整數 n
cin >> n;

// 再讀取一個字串
getline(cin, s);
cout << s << '\n';

// 最後再讀取第二個字串
getline(cin, s);
cout << s << '\n';

如果輸入的內容是像這樣:

> 2
> I love 
> APCS Guide

會發現程式的輸出有點奇怪:


I love 

這是因為 getline() 會讀取到 cin 最後沒吃掉的換行符號。 解決方法是在 getline() 前面加上 cin.ignore() 來解決這個問題。

以下是修改後的程式碼:

int n;
string s;

cin >> n;

cin.ignore(); // 這行會把換行符號忽略掉
getline(cin, s);
cout << s << '\n';

getline(cin, s);
cout << s << '\n';

這樣就可以正確讀取到兩個字串了!

輸出:

I love 
APCS Guide

另一種解決方案是多使用一次 getline() 來吃掉換行符號:

int n;
string s;

cin >> n;

getline(cin, s); // 這行會吃掉換行符號
getline(cin, s);
cout << s << '\n';

getline(cin, s);
cout << s << '\n';

這樣也可以正確讀取到兩個字串!

小測驗

getline(cin, str) 的功能是什麼?