【C++筆記】一些輸入函數 cin, getline(), cin.get() 等

cin

這大家都知道,這是 C++ 的標準輸入物件,屬於 istream 類別。

基本語法不外乎就是透過鍵盤輸入將資料存入某個變數。

1
2
int a;
cin >> a;

那其特性如下:

  • 以空白(空格、Tab 縮排、換行)為分隔符號。
  • 自動忽略前導空白字元(如輸入:1 2 3 4 5,每個數字間的空格都會忽略,並依序存入變數)
  • 無法讀取含有空白字元的字串,如下範例:
1
2
3
4
string name;
cin >> name;
// 輸入 John Doe
// name 只會得到 "John"

這是 cin 的缺點,要讀入完整的字串,則需要 getline()

printf() / scanf()

雖然本文講輸入函數,但想說既然 C 有的東西,C++ 當然也繼承下去,就順便講一講 printf()。

相對於 cin / cout 來說,printf() / scanf() 的執行效率遠高於前者,因為在底層進行實作,接近硬體層面。

其基本語法如下:

printf("字串格式化符號", 值1, 值2, ...)

scanf("字串格式化符號", &值1, &值2, ...)

使用前先引入 <cstdio>,或是 <stdio.h>,或是也可以不用寫。

1
2
3
4
5
6
7
8
9
10
#include <cstdio>

using namespace std;

int main(){
int a;
scanf("%d", &a);
printf("%d", a);
return 0;
}

Output(輸入 2 輸出 2):

1
2
2
2

字串結合格式化符號:

1
2
3
4
5
6
7
8
9
10
11
#include <cstdio>

using namespace std;

int main(){
int a;
printf("請輸入:");
scanf("%d", &a);
printf("你所輸入的是:%d", a);
return 0;
}

Output:

1
2
請輸入:2
你所輸入的是:2

& 取出變數 a 的記憶體位址,用於告訴 scanf 要將輸入的東西存到哪裡。

以下是一些常用的格式化符號:

類型符號說明
整數%d10 進位整數
%x, %X16 進位(小寫/大寫)
%o8 進位
字元%c單一字元
字串%s字元陣列
浮點數%f十進位浮點數
%.nf保留 n 位小數
%e, %E科學記號表示法
指標%p地址指標輸出
百分比符號%%輸出 % 本身

浮點數的格式化符號 %.nf 是比較常在考試中被拿出來講的東西:

1
2
3
4
5
6
7
8
9
#include <cstdio>

using namespace std;

int main(){
float a = 0.12345;
printf("%.2f", a); // 0.12345 只取小數點後兩位, 輸出即 0.12
return 0;
}

Output:

1
0.12

經典題:

1
2
3
4
5
6
7
8
9
10
#include <cstdio>

using namespace std;

int main(){
float a = 0.12345;
// %2.f 代表這個字串的總字元最小寬度為 2
printf("%2.f", a); // %2.f, 點後面沒東西預設就是 %2.0f
return 0;
}

Output:

1
0

輸出的 0 多了一個空格,因為 %2.f 的關係,要求總字元寬度至少要為 2,阿 0 只有一個字元,所以左邊補一個空格,就醬。

getline()

讀取整行字串,包含空格,直到遇到換行字元(\n)。

語法:

1
2
string line;
getline(cin, line);

若 getline 前面有 cin 的話,如下:

1
2
3
string a;
cin >> a;
getline(cin, line);

需要加上 cin.ignore(),去把前面 cin 留下的 \n 給忽略掉,避免影響到後續 getline() 讀取。

1
2
3
4
string a;
cin >> a;
cin.ignore();
getline(cin, line);

cin.get()

讀取單一字元,含空格與 '\n'

語法:

1
2
char ch;
cin.get(ch);

特性:

  • 不會忽略空白與換行,為 cin 的延伸版本。
  • 也可寫成:char ch = cin.get();

限制輸入字元:

1
2
3
char str[20];
cin.get(str, 20); // 讀取最多 19 字元,含空格
cout << str << endl;

在後面多加一個整數參數,即可限制要輸入多少個字元,從輸入中讀取最多 size-1 個字元(含空格),直到讀到 \n 或到達上限為止。

另外很重要的就是他會在結尾加上 '\0' 字元,表示字串到此結束。

也不會讀取 \n,會留在輸入緩衝區,所以若要繼續用 getline() 或 cin.get() 的時候,就用 cin.ignore() 清除。

如果緩衝區已經滿了,會發生 failbit,可用 cin.clear() 清除。

另外 cin.get() 也可自訂結束字元(delimiter),預設為 \n。若遇到指定的結束字元會停止讀取,但不會把 delimiter 取走。

具體語法如下:

1
cin.get(char *buffer, int size, char delim)

其實就是多加第三個參數,然後指定結束字元。

cin.getline()

這是用來填入字元陣列(C-style string)的方法。

語法:

1
2
char buf[100];
cin.getline(buf, 100);

特性:

  • getline() 相同,可讀取整行(含空格),但需指定緩衝區的大小。
  • 結尾自動加上 \0 表示字串結束,這是 C 語言的作法。

總結

1. cin

  • 標準輸入物件,屬於 istream 類別。
  • 特性
    • 以空白(空格、Tab 縮排、換行)為分隔符號。
    • 自動忽略前導空白。
    • 無法讀取含空格的字串,例如輸入 “John Doe” 只會取得 “John”。
    • 適用於基本輸入(整數、字串無空白等情形)。

2. getline()

  • 用於讀取整行字串(包含空格),直到 \n 為止。
  • 若前面有用 cin,需加 cin.ignore() 清除殘留的 \n
  • 語法:getline(cin, line);
    • line 是字串型態

3. cin.get()

  • 可讀取單一字元,含空白與換行
  • 語法有兩種:
    • cin.get(ch);
    • char ch = cin.get();
  • 也可限制讀取字元數:cin.get(buffer, size);,適用於 C-style 字串。
  • 可設定自訂的結束字元(delimiter),為 cin.get() 的第三個參數。

4. cin.getline()

  • 用於 C-style 字元陣列 的整行輸入。
  • 語法:cin.getline(buf, size);
  • 功能與 getline() 類似,但需指定緩衝區大小。
  • 自動在結尾加上 \0 字元。

5. scanf() / printf()(C 語言)

  • 執行效率較高,底層更貼近硬體。
  • 格式化控制更細緻,如 %d%f%.2f 等。
  • 使用需引入 <cstdio><stdio.h>,也可以不用加。
  • 別忘了用 scanf() 時,要存入的變數都要在前面加上 & 取址運算子。

結語

  • 各輸入方式適用場景不同:
    • cin:單一基本型態。
    • getline():讀取整行含空白的 string
    • cin.get() / cin.getline():操作細緻、支援 C-style 字元陣列。
    • scanf():效率高、格式化明確,但較不安全(如緩衝區溢位問題)。

參考資料

C++中cin、cin.get()、cin.getline()、getline()、gets()等函数的用法 - flatfoosie - 博客园

cin get() in C++ with Examples | geeksforgeeks

printf 與 scanf

如何在 C++ 中使用 scanf() & printf()_c++scanf函数-CSDN博客