目次
1. 前言
C語中空白輸出的意義
C語在撰寫程式時,「空白(space)」的輸出並非僅是裝飾。它關係到輸出結果的排版、可讀性、資料顯示的可視性提升等,於實務上也在許多情境中必須使用。特別是當以表格形式輸出或進行位數對齊時,了解空白的處理方式相當重要。 例如,當同時輸出多個數值或字串時,善用空白即可實現美觀的輸出。相反地,若空白處理錯誤,輸出會出現錯位,或無法呈現預期的外觀。意外容易卡關的「空白」輸出
對於剛開始學習 C 語的初學者而言,「空白的輸出」往往是意想不到的陷阱。若僅是輸出空格,只要寫上 ” ” 即可,但若涉及 Tab、對齊、動態指定空白數量等稍微進階的應用,就需要相關知識。此外,printf 函式的格式指定子以及與迴圈結合的空白輸出等,也常成為混亂的來源。本篇文章可學到的內容
本文將針對「C 語 空白 輸出」進行說明,清楚解說以下內容。- 空白字元的種類與使用分別
printf
的基本空白輸出- 活用空白的排版技巧
- 常見錯誤與其對策
- 實作範例與 FAQ
2. 空白字元是什麼?從基礎開始了解
空白字元的定義與角色
在 C 語言中,「空白字元」指的是在螢幕上不會顯示任何內容,或以空格形式顯示的特殊字元。空白字元在外觀上不顯眼,但對字串的分隔與顯示排版有很大影響。它不只是裝飾,而是構建輸出版面的控制元素。 在 C 語言中,以下這些空白字元常被使用。常用的空白字元類型
1. 空格(' '
)
最基本的空白字元,可透過鍵盤的「空格鍵」輸入一個字元的空白。用於想要在顯示間隔上留出一個字元的情況。printf("Hello World"); // 「Hello」與「World」之間有一個空格
2. Tab()
Tab 是用於以固定寬度移動游標的控制字元。通常被視為相當於8 個字元的空白,但會因終端機或編輯器的設定而有所不同。printf("Name Score"); // 「Name」與「Score」之間的 Tab 空白
3. 換行(`
`) 換行字元顧名思義,是將輸出位置移至下一行的控制字元。它較偏向用於換行的目的,但因對外觀排版有很大影響,亦可被視為廣義的空白字元。printf("Line 1
Line 2"); // 輸出分為兩行
空白字元對程式的影響
這些空白字元會直接影響程式碼的執行結果。例如,數值或字串的顯示位置、輸入的分隔,甚至語法解析的行為都與之相關。特別是初學者容易混淆的是,scanf
與gets
等輸入處理時空白的處理方式(此部分將於後述)。 此外,若想有意插入多個空白,僅僅連續寫空格是不夠的,還需要使用迴圈或格式指定子的情況也存在。總結:空白字元是「看不見卻重要」
空白字元因為是看不見的存在,常被初學者忽視。然而,作為支撐程式外觀與功能性兩者的基礎,必須正確理解並適當使用。 在下一章,我們將說明在 C 語言中使用printf
函式輸出空白的最基本方法。3. printf 輸出空白的基礎
printf 是什麼?空白輸出的基本函式
C 語言中用於將文字或數值輸出到螢幕的代表性函式是printf
。此函式不僅會直接輸出字串中所寫的內容,還能使用 格式指定子 來細緻控制數值與字串的顯示方式。 即使想要輸出空白,只要使用 printf
也能輕鬆輸出包含空格或 Tab 的內容。以下介紹幾種常見的方法。在字串中直接寫入空格
最簡單的方法是,在雙引號包住的字串中 直接寫入空格。printf("Hello World
");
此程式碼會在「Hello」與「World」之間輸出一個空格。若想連續輸出多個空格,則可如以下插入多個空格。printf("Hello World
"); // 空格3個
使用 Tab 字元(\t)輸出空白
若想留較大的空白,使用 Tab 字元也是一種方法。使用 \t 可以一次插入依環境而定的固定空白寬度(通常為 8 個字元)。printf("Name Score
");
printf("Alice 90
");
printf("Bob 85
");
輸出結果如下(為了易讀而做了排版):Name Score
Alice 90
Bob 85
但因 Tab 的寬度取決於編輯器或終端機的設定,在需要精確排版的情況下建議使用空格。使用格式指定子控制空白
作為printf
的強大功能,可利用格式指定子的寬度進行包含空白的排版輸出。指定數值或字串的輸出寬度
printf("%5d
", 42); // 寬度5右對齊(空格3個+42)
printf("%-5d
", 42); // 寬度5左對齊(42+空格3個)
字串的情況亦同
printf("%10s
", "C"); // 右對齊,空格9個+"C"
printf("%-10s
", "C"); // "C"+空格9個
透過指定格式寬度,顯示的對齊會變得更容易。實例:利用空白進行位數對齊
以下為將多個數值對齊後輸出的範例。printf("No Score
");
printf("%-3d %5d
", 1, 100);
printf("%-3d %5d
", 2, 85);
printf("%-3d %5d
", 3, 92);
輸出結果:No Score
1 100
2 85
3 92
透過使用空白整理欄位,可得到易讀且外觀良好的輸出。總結:printf 是空白輸出的基本工具
只要使用printf
,不僅能輕鬆輸出空白,還能自由調整排版與位數對齊等外觀。從直接寫入空格或 Tab 開始,到使用格式指定子控制寬度,依情況適當選擇使用方式是很重要的。4. 多空格輸出技巧彙總【含實用範例】
為什麼需要輸出「多個空格」?
在 C 語言中,為了格式化輸出結果與提升可讀性,常常需要輸出不只一個字元的多個空格。例如,將標題與資料錯開顯示,或統一縮排以調整外觀。 僅僅像" "
那樣寫多個空格也能實現,但若想輸出可變長度的空格,僅此方式不足。本章將介紹因應不同情況的空格輸出技巧。使用 for 迴圈重複輸出空格
若想以可變長度輸出空格,最具彈性的方法是 使用迴圈(for 迴圈)的方法。範例:輸出 5 個空格
for (int i = 0; i < 5; i++) {
printf(" ");
}
這樣寫的話,就能依變數或條件調整空格數量,實用性很高。應用:加上縮排輸出字串
int indent = 4;
for (int i = 0; i < indent; i++) {
printf(" ");
}
printf("Hello, World!
");
輸出: Hello, World!
使用 printf 與格式指定子動態控制空格
printf
具備 可用變數指定格式寬度的功能。使用此功能即可不使用迴圈直接輸出多個空格。範例:動態輸出 10 個字元寬度的空格
printf("%*s", 10, ""); // 10個字元寬度的空格
此程式碼會將空字串 ""
以指定寬度(此處為 10)右對齊,因而輸出 10 個空格。應用:在數值前插入空格以格式化
int n = 42;
printf("%5d
", n); // 輸出: 「 42」 (空格3個)
也可用於數值對齊顯示,對表格形式的輸出很方便。建立專用的空格輸出函式
若在多處需要輸出空格,準備專用函式會很方便。範例:輸出任意數量空格的函式
void print_spaces(int count) {
for (int i = 0; i < count; i++) {
printf(" ");
}
}
使用方式:print_spaces(8);
printf("Indented Text
");
輸出: Indented Text
程式碼的可讀性也會提升,實務上也能活用。實用範例:資料的對齊顯示
以下是利用空格對齊多行資料以表格形式顯示的範例。printf("No Name Score
");
printf("%-3d %-10s %5d
", 1, "Alice", 100);
printf("%-3d %-10s %5d
", 2, "Bob", 85);
輸出:
No Name Score
1 Alice 100
2 Bob 85
總結:依需求選擇空格輸出方法
要輸出多個空格,依情況選擇以下三種方法很重要。- 固定空格時直接寫
" "
- 可變空格時使用
for
迴圈或print_spaces
函式 - 使用格式指定子簡潔地指定輸出寬度也是有效的
5. 在格式化輸出中活用空白的方法
什麼是輸出格式化?
「格式化輸出」是指以指定的格式顯示資料。在 C 語言中,需要善用空白,使數值和字串更易閱讀、對齊輸出。透過整理輸出,可向讀者提供高可視性的結果,特別是在主控台應用程式與除錯輸出中相當重要。位數對齊與右對齊、左對齊的使用區別
C 語言的printf
函式中,透過設定格式指定子的寬度,可控制位數對齊與對齊方向。數值的右對齊
int score = 95;
printf("%5d
", score); // 寬度5的右對齊(3個空白 + 95)
出力例: 95
字串的左對齊
char name[] = "Alice";
printf("%-10s
", name); // 寬度10的左對齊(Alice + 5個空白)
出力例:Alice
結合使用以表格形式呈現
printf("%-10s %5d
", "Bob", 80);
printf("%-10s %5d
", "Charlie", 92);
出力例:Bob 80
Charlie 92
%*d
與 %*s
的動態格式化
如果想以變數指定格式寬度,可使用 *
。這是在執行時決定寬度的便利功能。範例:以變數指定寬度
int width = 8;
int value = 42;
printf("%*d
", width, value); // 寬度8的右對齊
出力例: 42
若要左對齊,請加上 -
printf("%-*s
", width, "C"); // 左對齊並補空白
Tab 與空格的使用區別
空白分為空格與 Tab 兩種,但在格式化輸出時,空格往往能得到較穩定的結果。Tab 範例(在不同環境可能會錯位)
printf("Name Score
");
看起來可以輕鬆對齊,但 Tab 寬度依賴環境,可能會導致顯示錯位的風險。使用空格較為可靠
printf("%-10s %5s
", "Name", "Score");
這樣較容易控制,且更容易重現預期的外觀。常見的輸出格式化模式
以下實務中常見的輸出格式化使用案例。資料的列表顯示
printf("No Name Score
");
printf("%-3d %-10s %5d
", 1, "Alice", 100);
printf("%-3d %-10s %5d
", 2, "Bob", 85);
數值的位數對齊
printf("%05d
", 42); // 以零填充輸出5位 → 00042
透過使用零填充與空白填充的區別,可進行機械式與視覺式的格式化。
總結:格式化輸出是提升可讀性的第一步
在 C 語言的格式化輸出不僅僅是「讓畫面好看」而已,也是傳遞資訊結構的視覺化重要技巧。透過空白的格式化,可大幅提升可讀性與管理的便利性。 至此介紹的技術不僅適用於主控台輸出,也可應用於日誌輸出與 CSV 檔案的產生。掌握格式指定子的運用,讓空白能自由控制吧。6. 含空格字串的處理【輸入與輸出注意事項】
什麼是含空格的字串?
C語言中,含空格的字串(例如:「Hello World」或「My name is John」)在輸入與輸出時需要特別注意。特別是在輸入時,字串會因空格而被切斷,導致無法正確取得預期的資料。 本章將說明正確處理含空格字串的技巧與注意事項。scanf 的輸入對空格較弱
scanf("%s", str);
使用時,讀取字串會在遇到空格(空白、Tab、換行等)即結束輸入。範例:輸入在中途被截斷
char str[100];
scanf("%s", str); // 輸入: Hello World
在此情況下,變數 str
只會收到 "Hello"
,World
會被忽略。使用 fgets 也能取得含空格的字串
若想正確取得含空格的字串,建議使用fgets()
函式。範例:使用 fgets 取得整行
char line[100];
fgets(line, sizeof(line), stdin);
fgets()
會持續讀取字串,直到遇到換行或達到指定大小。即使是含空格的句子,也能安全地一次取得整行。 ※但有時字串最後會包含換行字元,通常需要依需求進行去除處理。line[strcspn(line, "\n")] = ' '; // 刪除換行
應避免使用 gets 函式
過去曾使用gets()
來輸入含空格的字串,但因為存在緩衝區溢位的危險,已不建議使用。在目前的 C 標準(C11 以上)已被廢除。請改用 fgets()
。輸出時不需要特別處理
在輸出含空格的字串時,無需特別處理。使用printf()
或 puts()
即可直接顯示。範例:輸出含空格的字串
char message[] = "Hello World with space";
printf("%s
", message); // 輸出: Hello World with space
應用:結合輸入與格式化
以下示範如何接收含空格的輸入,並將其格式化後顯示。char name[100];
printf("請輸入姓名:");
fgets(name, sizeof(name), stdin);
name[strcspn(name, "\n")] = ' '; // 刪除換行
printf("你好,%-20s!\n", name); // 左對齊格式化
這樣即可正確接收含空格的姓名,並進行格式化顯示。總結:含空格的字串使用「fgets」安全處理
在 C 語言中,僅使用scanf
無法完整處理含空格的字串,使用 fgets
可安全且精確地取得輸入。輸出方面使用 printf
沒有問題,但因為常與輸入一起使用,對空格字元的了解與謹慎設計相當重要。7. 常見錯誤與問題處理方法
處理空白時,初學者容易陷入的陷阱是什麼?
C語言中「空白的輸出」看似簡單,卻是 初學者非常常卡住的重點之一。會出現非預期的輸出結果、排列顯示崩壞、輸入資料在中途被截斷等,與空白相關的問題不勝枚舉。 本章將具體說明 空白輸出與格式化常見錯誤及其對策。錯誤 1:使用 scanf
無法正確讀取含空白的字串
原因:
scanf("%s", str);
會因空白或換行而截斷輸入,導致只能讀取到字串的一部分。解決方法:
使用fgets()
讀取整行,必要時再移除換行字元。fgets(str, sizeof(str), stdin);
str[strcspn(str, "
")] = ' '; // 移除換行
錯誤 2:輸出結果未對齊
原因:
格式指定子的寬度不適當,或數字位數不一致,卻直接使用%d
或 %s
。解決方法:
- 使用像
%5d
或%-10s
明確指定輸出寬度 - 將數值右對齊、字串左對齊,便於對齊。
printf("%-10s %5d
", "Alice", 100);
printf("%-10s %5d
", "Bob", 85);
錯誤 3:使用 Tab()嘗試對齊卻出現錯亂
原因:
Tab 字元不是「固定寬度」,而是 以 8 個字元為單位對齊。根據字元數會產生位置偏移的可能性。解決方法:
使用空格與格式指定子明確控制白。// ❌ 不穩定的輸出
printf("Name Score
");
// ✅ 穩定的輸出
printf("%-10s %5s
", "Name", "Score");code>
錯誤 4:printf("%*s", n, "")
的用法錯誤
原因:
在%*s
中,若將字串指定為 " "
(空格),可能無法得到預期的空白。解決方法:
透過傳入 空字串""
,即可輸出 n 個空白。int n = 5;
printf("%*s", n, ""); // 輸出 5 個空白
錯誤 5:混淆零填充(%05d
)與空白填充(%5d
)
原因:
本想使用%05d
來對齊數字,卻被填入了與預期不同的「零」。解決方法:
- 零填充:
%05d
→00042
- 空白填充:
%5d
→42
問題發生時的檢查清單
- 輸入處理有使用
scanf
- 輸出時有明確指定 格式寬度 嗎?
- 有使用空格而非 Tab 嗎?
- 字串或數值是否符合預期長度(使用
strlen()
確認)
總結:空白問題可透過「理解」防止
與空相關的問題,只要了解其機制就能大多避免。特別是掌握printf
的格式化指定子與 fgets
的輸入處理,空白的輸出與格式化就能順利進行。 當問題發生時,請以「為何此空白未顯示」以及「在哪裡輸入被截斷」的觀點,冷靜地檢視程式碼。8. 實作:活用空白輸出的小練習(可直接複製)
在實作中學習空白輸出
透過實際使用至今所解說的空白輸出、格式化與輸入的處理方式,能更深入理解。本節提供了三個以鞏固學習並提升應用能力為目的的實作練習。全部都附有可直接複製貼上執行的程式碼,請務必在手邊的開發環境中試跑看看。練習1:以表格形式排列資料並輸出
目的:
將多筆姓名與分數,以表格般易於閱讀的方式排列顯示。範例程式碼:
#include <stdio.h>
int main() {
printf("%-10s %-10s %5s
", "ID", "Name", "Score");
printf("%-10s %-10s %5d
", "S001", "Alice", 95);
printf("%-10s %-10s %5d
", "S002", "Bob", 88);
printf("%-10s %-10s %5d
", "S003", "Charlie", 100);
return 0;
}
執行結果:
ID Name Score
S001 Alice 95
S002 Bob 88
S003 Charlie 100
說明:
%10s
用於指定字串寬度,左對齊(%-10s
) 進行格式化。%5d
用於數值的右對齊排列。
練習2:以空白再現段落縮排(Indent)
目的:
將多行文字,各自以固定空格進行縮排後顯示。範例程式碼:
#include <stdio.h>
void print_indent(int n) {
for (int i = 0; i < n; i++) {
printf(" ");
}
}
int main() {
int indent = 4;
print_indent(indent); printf("這是第一段。
");
print_indent(indent); printf("使用縮排進行格式化。
");
print_indent(indent); printf("空白的輸出提升可讀性。
");
return 0;
}
執行結果:
這是第一段。
使用縮排進行格式化。
空白的輸出提升可讀性。
說明:
- 以使用者自訂函式輸出空白。
- 具備高維護性與可重用性的技巧。
練習3:以空白製作裝飾式標題輸出
目的:
將標題文字置中,並以空白環繞製作「裝飾顯示」。範例程式碼:
#include <stdio.h>
#include <string.h>
_centered(char *text, int width) {
int pad = (width - strlen(text)) / 2;
for (int i = 0; i < pad; i++) printf(" ");
printf("%s
", text);
}
int main() {
int line_width = 40;
printf("========================================
");
print_centered("== 程式開始 ==", line_width);
printf("========================================
");
return 0;
}
執行結果(建議使用等寬字型):
========================================
== 程式開始 ==
========================================
說明:
strlen()
用於動態計算置中所需的空白數。- 可應用於使用者介面與日誌輸出。
總結:空白的使用方式成為「呈現力」
透過這些練習,您應該能體會到空白的輸出不只是單純的外觀調整,而是提升程式可讀性與表現力的要素。 請務必在實務或學習中活用此技巧。9. 總結
空白是「看不見卻強大的工具」
在本文中,我們聚焦於C語言中的空白輸出方法,並從基礎到實踐逐步說明。空白這種肉眼難以看見的存在,正是影響程式可讀性與易用性的力量,我想您已經了解了。回顧本文所學內容
- 空白字元的種類及其角色(空格、Tab、換行)
- 使用
printf
函式的基本空白輸出方法 - 活用空白的排版技巧
- 含有空白之字串的輸入/輸出注意事項
- 常見錯誤及其原因與對策
- 透過實作練習鞏固理解
空白輸出的技能可應用於多種情境
此技能不僅限於單純的主控台輸出,亦可在以下領域發揮作用:- 日誌輸出的排版(運維上重要)
- 表格形式資料的顯示
- CSV 與文字檔的排版輸出
- 以 UI/UX 為考量的終端機應用程式開發
最後:先從「有意識地使用空白」開始
空白若不加以意識,就只是普通的留白。然而,若有意地活用,便能提供對閱讀者友善且條理分明的輸出。 請在未來的程式設計中,有意識地使用「空白」,朝向整潔的程式碼與輸出邁進。10. FAQ(常見問題)
Q1. printf
要如何輸出多個空白?
A. 有幾種方法。最簡單的是在雙引號內寫多個空格的方式:printf(" "); // 輸出5個空白
如果想動態決定空白的數量,以下方法也很方便:printf("%*s", 5, ""); // 輸出5個空白
或者,也可以使用迴圈輸出的方式:for (int i = 0; i < 5; i++) printf(" ");
Q2. scanf("%s", str);
無法輸入含有空白的字串。該怎麼辦?
A. scanf("%s", str);
會因空白(空格、Tab、換行)而將輸入分割,無法正確取得含空白的字串。此時請使用 fgets()
。char str[100];
fgets(str, sizeof(str), stdin);
str[strcspn(str, "
")] = ' '; // 刪除換行
這樣就能安全地取得含空白的一行字串。Q3. %5d
與 %05d
的差異是什麼?
A. 兩者皆將輸出寬度固定為5個字元,但填充的字元不同。%5d
→ 以空白填充,右對齊%05d
→ 以零填充,右對齊
範例:
printf("%5d
", 42); // 「 42」
printf("%05d
", 42); // 「00042」
請依照外觀與用途加以選擇使用。Q4. Tab(\t
)與空格(' '
)該使用哪一個?
A. 基本上建議使用空格。因為 Tab 在不同環境下顯示寬度會不同,可能導致對齊錯亂。- 如果只想簡單留空,使用 Tab 也可以
- 在需要嚴格排版或對齊時,請使用空格與格式指定子。
Q5. printf("%*s", n, "")
無法正確輸出空白。為什麼?
A. 此語法的作用是「在寬度 n 的位置輸出空字串」。如果錯誤地將 " "
(空格)指定為字串,會導致只輸出 1 個空白。
正確的用法:int n = 5;
printf("%*s", n, ""); // 輸出5個空白
Q6. 可以只寫一個只負責輸出空白的函式嗎?
A. 當然可以,且在實務上也被建議。對於需要重複輸出空白的情況,提供專用函式能提升可讀性與可重用性。void print_spaces(int count) {
for (int i = 0; i < count; i++) {
printf(" ");
}
}
呼叫範例:print_spaces(8);
printf("Indented text
");
Q7. 排版對齊無法正常工作。應該先檢查什麼?
A. 請確認以下要點:- 格式指定子的寬度是否適當(例如:
%-10s
,%5d
) - 資料的位數或長度是否有差異
- 是否使用空格而非 Tab
- 字串或數值是否符合預期長度(使用
strlen()
確認)