
C言語のきほん|文字を変換する(toupper、tolower)
大文字と小文字を思いどおりに変える。toupper と tolower で文字変換の基本をやさしく身につけよう
C言語で文字を扱っていると、「小文字を大文字にそろえたい」「大文字を小文字に変えたい」といった場面がよくあります。
たとえば、ユーザーが入力した英字を見やすく整えたり、大文字と小文字の違いをそろえて比較しやすくしたり、表示用の文字列を整形したりするときです。
こうしたときに役立つのが、文字を変換する関数である toupper と tolower です。
- toupper は、小文字を大文字に変換する関数
- tolower は、大文字を小文字に変換する関数
どちらも ctype.h に用意されている標準ライブラリ関数で、文字コードの並び方を自分で意識しなくても、安全に文字変換を行えるのが大きな特徴です。
たとえば、C言語を学び始めたころには、
if (c >= 'a' && c <= 'z') {
c = c - ('a' - 'A');
}のように、自分で文字コードの差を使って変換を書くこともできます。
でも、この方法は文字コードの並び方に依存した書き方です。
それに対して toupper や tolower を使えば、「英小文字なら大文字にする」「英大文字なら小文字にする」という意図を、そのままシンプルに書けます。
さらに便利なのは、英字以外の文字はそのまま返すという点です。
つまり、数字や記号、空白などに対して無理に変換しようとせず、必要な文字だけを自然に変換してくれます。
この節では、toupper と tolower の基本的な使い方に加えて、
- どのような文字が変換されるのか
- 変換されない文字はどうなるのか
- getchar と組み合わせて1文字ずつ変換する方法
- 文字列全体を順番に変換する考え方
- 実践問題としてどのように応用できるのか
まで、順番にていねいに見ていきます。
文字変換の関数はとてもシンプルですが、入力チェックや文字列整形の基本としてとても大切です。
ここでしっかり身につけておくと、あとで文字列比較や文字列処理をするときにも役立ちます。
文字を変換する関数とは
文字を変換する関数とは、入力された文字が英字であれば、その大文字・小文字を変換して返す関数です。
今回扱うのは次の2つです。
| 関数名 | 役割 |
|---|---|
| toupper | 英小文字を英大文字に変換する |
| tolower | 英大文字を英小文字に変換する |
たとえば、
| 入力 | toupper の結果 | tolower の結果 |
|---|---|---|
| a | A | a |
| B | B | b |
| 5 | 5 | 5 |
| % | % | % |
この表からわかるように、英字以外の文字は変換されず、そのまま返されます。
この性質のおかげで、文字を1つずつ順番に調べながら変換したいときでも、「英字かどうかを毎回自分で細かく判定してから変換する」手間を減らしやすくなります。
toupper 関数とは
toupper は、英小文字を英大文字に変換する関数です。
関数宣言
#include <ctype.h>
int toupper(int c);機能
引数 c が英小文字なら、対応する英大文字に変換して返します。
それ以外の文字なら、そのまま返します。
返却値
| 条件 | 返却値 |
|---|---|
| 英小文字 | 対応する英大文字 |
| それ以外 | 入力された文字そのもの |
使用例
int c = 'a';
c = toupper(c);この場合、c には A が入ります。
tolower 関数とは
tolower は、英大文字を英小文字に変換する関数です。
関数宣言
#include <ctype.h>
int tolower(int c);機能
引数 c が英大文字なら、対応する英小文字に変換して返します。
それ以外の文字なら、そのまま返します。
返却値
| 条件 | 返却値 |
|---|---|
| 英大文字 | 対応する英小文字 |
| それ以外 | 入力された文字そのもの |
使用例
int c = 'Z';
c = tolower(c);この場合、c には z が入ります。
なぜ int 型を使うのか
toupper や tolower の引数と返却値は int 型です。
これは getchar などの文字入力関数と同じく、EOF のような特別な値を扱いやすくするためでもあります。
学習の初期では、英字を変換するときに
char ch;のように char 型で扱うこともありますが、getchar と組み合わせるなら int 型を使うのが基本です。
たとえば、
int c;
c = getchar();
c = toupper(c);のように書くと、EOF の扱いも含めて自然に処理できます。
どんな文字が変換されるのか
toupper と tolower は、英字だけを対象に変換します。
数字や記号、空白文字などは変換しません。
| 入力文字 | toupper | tolower | 説明 |
|---|---|---|---|
| a | A | a | 小文字なので大文字化できる |
| m | M | m | 小文字なので大文字化できる |
| A | A | a | 大文字なので小文字化できる |
| Z | Z | z | 大文字なので小文字化できる |
| 7 | 7 | 7 | 数字なので変化しない |
| % | % | % | 記号なので変化しない |
| 空白 | 空白 | 空白 | 空白なので変化しない |
この「英字以外はそのまま」という性質はとても便利です。
たとえば、文字列全体を順番に変換するとき、数字や記号が混ざっていても安心して処理できます。

この図では、入力文字に対して toupper と tolower がどのように働くかをまとめています。
英字は大文字・小文字に応じて変換されますが、数字や記号はそのまま返されることがわかります。
この性質を理解しておくと、文字列全体をまとめて処理するときにも安心して使えます。
シンプルなプログラム例
キーボードから文字を繰り返し入力し、小文字なら大文字に変換して表示するプログラムです。
ファイル名:12_9_1.c
#include <stdio.h>
#include <ctype.h>
int main(void)
{
int c;
printf("文字を続けて入力してください。(終了条件:Ctrl+Z または Ctrl+D)\n");
while ((c = getchar()) != EOF) {
/* 改行文字は表示しない */
if (c == '\n') {
continue;
}
/* 小文字を大文字に変換する */
c = toupper(c);
printf("変換後の文字: %c\n", c);
}
return 0;
}このプログラムのポイント
このプログラムでは、getchar で1文字ずつ入力を受け取り、それを toupper に渡しています。
特に大事なのは次の2点です。
getchar の返り値を int 型で受けている
int c;としています。
これは EOF を正しく扱うためです。
改行文字をスキップしている
if (c == '\n') {
continue;
}getchar は Enter キーによる改行文字も読み込みます。
そのまま変換してしまうと見づらくなるので、この例では改行を表示対象から外しています。
実行イメージ
たとえば、次のように入力したとします。
a
B
5
%すると、表示は次のようになります。
変換後の文字: A
変換後の文字: B
変換後の文字: 5
変換後の文字: %この結果からも、toupper は小文字だけを大文字に変換し、それ以外はそのまま返していることがわかります。
文字列全体を変換する考え方
toupper や tolower は1文字単位の関数です。
そのため、文字列全体を変換したいときは、文字列を先頭から順番に1文字ずつ見ていきます。
たとえば、文字列 Hello を全部大文字にしたいなら、
- H を変換する
- e を変換する
- l を変換する
- l を変換する
- o を変換する
- \0 で終了する
という流れになります。
つまり、配列を順番にたどりながら、それぞれに toupper や tolower を適用していくわけです。
toupper と tolower の使い分け
この2つの関数は、役割が反対です。
| 目的 | 使う関数 |
|---|---|
| 小文字を大文字にそろえる | toupper |
| 大文字を小文字にそろえる | tolower |
たとえば、すべて大文字で表示したいなら toupper を使います。
逆に、入力された英字をすべて小文字に統一したいなら tolower が向いています。
実践問題
Ctrl + Z(UNIX/Linux では Ctrl + D)が入力されるまで文字を連続して入力し、
英大文字、英小文字、数字、記号の個数を数えて表示するプログラムを作成してください。
ただし、空白類文字は数えないものとします。
解答例
ファイル名:12_9_2.c
#include <stdio.h>
#include <ctype.h>
int main(void)
{
int c;
int upper_count = 0;
int lower_count = 0;
int digit_count = 0;
int symbol_count = 0;
printf("文字を入力してください。(終了条件:Ctrl+Z または Ctrl+D)\n");
while ((c = getchar()) != EOF) {
if (isspace(c)) {
continue;
}
if (isupper(c)) {
upper_count++;
} else if (islower(c)) {
lower_count++;
} else if (isdigit(c)) {
digit_count++;
} else {
symbol_count++;
}
}
puts("");
puts("文字種別ごとの個数");
printf("英大文字: %d\n", upper_count);
printf("英小文字: %d\n", lower_count);
printf("数字: %d\n", digit_count);
printf("記号: %d\n", symbol_count);
return 0;
}解説
この問題では、toupper や tolower そのものではなく、同じ ctype.h の文字判定関数を組み合わせています。
文字変換の前に、どの種類の文字かを見分ける練習としてちょうどよい問題です。
isspace で空白類を除外している点もポイントです。
実践問題
入力された文字列に対して、次の変換を行うプログラムを作成してください。
- 英大文字は英小文字に変換する
- 英小文字は英大文字に変換する
- 空白文字や英字以外はそのまま残す
解答例
ファイル名:12_9_3.c
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(void)
{
char str[100];
printf("文字列を入力してください(最大99文字)> ");
if (fgets(str, sizeof(str), stdin) == NULL) {
puts("入力エラーが発生しました。");
return 1;
}
size_t len = strlen(str);
if (len > 0 && str[len - 1] == '\n') {
str[len - 1] = '\0';
}
for (int i = 0; str[i] != '\0'; i++) {
if (isupper((unsigned char)str[i])) {
str[i] = (char)tolower((unsigned char)str[i]);
} else if (islower((unsigned char)str[i])) {
str[i] = (char)toupper((unsigned char)str[i]);
}
}
puts("変換後の文字列:");
printf("[%s]\n", str);
return 0;
}解説
この問題では、1文字ずつ順番に調べながら、大文字は小文字へ、小文字は大文字へ変換しています。
英字以外は何もしないので、そのまま残ります。
toupper と tolower を実際に文字列全体へ応用する練習としてとても良い問題です。
実践問題
空白とタブを含む文字列を入力し、次のように整形するプログラムを作成してください。
- 連続した空白とタブは1つのスペースにまとめる
- 文字列の先頭と末尾の空白は取り除く
- 入力に失敗したらエラーメッセージを表示して return 1; で終了する
解答例
ファイル名:12_9_4.c
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(void)
{
char src[200];
char dest[200];
int i = 0;
int j = 0;
int in_space = 1;
printf("文字列を入力してください> ");
if (fgets(src, sizeof(src), stdin) == NULL) {
puts("入力エラーが発生しました。");
return 1;
}
size_t len = strlen(src);
if (len > 0 && src[len - 1] == '\n') {
src[len - 1] = '\0';
}
while (src[i] != '\0') {
if (src[i] == ' ' || src[i] == '\t') {
if (!in_space) {
dest[j++] = ' ';
in_space = 1;
}
} else {
dest[j++] = src[i];
in_space = 0;
}
i++;
}
if (j > 0 && dest[j - 1] == ' ') {
j--;
}
dest[j] = '\0';
puts("結果の文字列:");
printf("\"%s\"\n", dest);
return 0;
}解説
この問題は toupper や tolower の直接利用ではありませんが、ctype.h を使う文字処理の考え方を広げる練習としてよい問題です。
空白の連続をまとめる処理では、直前が空白中かどうかを表すフラグ in_space を使っています。
文字列を1文字ずつ順番に見て処理する、という点では文字変換と同じ考え方が活きています。
文字変換関数を使うときの考え方
toupper と tolower を使うときは、次の流れで考えると整理しやすいです。
| 手順 | 内容 |
|---|---|
| 1 | 1文字だけ変換したいのか、文字列全体を変換したいのか考える |
| 2 | 小文字を大文字にするなら toupper を選ぶ |
| 3 | 大文字を小文字にするなら tolower を選ぶ |
| 4 | 文字列なら \0 まで順に処理する |
| 5 | 英字以外はそのまま残ることを理解しておく |
この流れを意識すると、文字変換の処理がとても書きやすくなります。
よくある使い方
| やりたいこと | 使う関数 | 例 |
|---|---|---|
| 小文字を大文字にそろえる | toupper | abc → ABC |
| 大文字を小文字にそろえる | tolower | ABC → abc |
| 入力文字を統一する | toupper / tolower | yes, YES, Yes を同じ形に近づける |
| 見やすく整形する | toupper / tolower | 表示用の文字列を整える |
| 判定前に文字を統一する | tolower など | 比較しやすい形にそろえる |
toupper と tolower を学ぶ意味
この2つの関数はとてもシンプルですが、文字処理の基本としてとても重要です。
| 学べること | 内容 |
|---|---|
| 英字変換の基本 | 大文字と小文字の変換方法 |
| 文字ごとの処理 | 1文字ずつ順番に扱う考え方 |
| 英字以外の扱い | 数字や記号はそのまま残ること |
| 入出力との連携 | getchar や fgets と組み合わせる方法 |
| 文字列処理への応用 | 配列を順にたどって変換する方法 |
toupper と tolower を使えるようになると、入力文字を整えたり、表示形式をそろえたり、比較しやすい形に変換したりと、文字列処理の幅がぐっと広がります。
とても基本的な関数ですが、実際のプログラムでは何度も登場する大切な道具です。
