記事内にはプロモーションが含まれています

【C言語】大文字と小文字を変換する方法!toupper/tolower関数やASCIIコードの計算ロジック

【C言語】大文字と小文字を変換する方法!toupper/tolower関数やASCIIコードの計算ロジック C言語

C言語で文字列操作を行っていると、ユーザーの入力を統一したり、大文字・小文字を区別せずに検索を行ったりするために、文字のケース(大文字・小文字)を変換したい場面が頻繁にあります。

「’a’ を ‘A’ にしたい」「文字列全体を小文字に統一したい」といった要望は、C言語の標準ライブラリを使えば簡単に実現できます。

また、コンピュータが文字を扱う仕組み(ASCIIコード)を知っていれば、関数を使わずに計算だけで変換することも可能です。

この記事では、C言語における大文字・小文字の変換方法について、ctype.h の標準関数を使った安全な方法から、ASCIIコードの性質を利用した計算テクニック、さらには文字列全体を変換する自作関数の実装例まで、詳しく解説します。

【本記事の信頼性】
プロフィール
執筆者:マヒロ
  • 執筆者は元エンジニア
  • SES⇒大手の社内SE⇒独立
  • 現在はこじんまりとしたプログラミングスクールを運営
  • モットーは「利他の精神」

標準ライブラリ関数 toupper / tolower を使う方法

最も一般的で推奨される方法は、C言語の標準ライブラリである ctype.h ヘッダに含まれる関数を使用することです。

これらの関数は、文字が変換可能かどうかを自動的に判断してくれるため、バグの少ない安全なコードを書くことができます。

1文字を大文字・小文字に変換する

大文字への変換には toupper 関数、小文字への変換には tolower 関数を使用します。

なお、touppertolower の引数には、unsigned char として表現可能な値(または EOF)を渡す必要があります。

char 型が符号付き(signed)の環境で負の値(日本語などのマルチバイト文字の一部など)が渡されると未定義動作となるため、安全のために必ず (unsigned char) にキャストして渡すのが定石です。

#include <stdio.h>
#include <ctype.h> // 変換関数を使うために必要

int main(void) {
    char ch1 = 'a';
    char ch2 = 'Z';
    char ch3 = '9'; // アルファベット以外

    // 小文字 -> 大文字
    // 安全のために (unsigned char) にキャストする
    char upper = toupper((unsigned char)ch1);
    
    // 大文字 -> 小文字
    char lower = tolower((unsigned char)ch2);

    // 変換不要な文字(そのまま返される)
    char number = toupper((unsigned char)ch3);

    printf("元の文字: %c -> toupper: %c\n", ch1, upper);
    printf("元の文字: %c -> tolower: %c\n", ch2, lower);
    printf("元の文字: %c -> toupper: %c\n", ch3, number);

    return 0;
}

実行結果

元の文字: a -> toupper: A
元の文字: Z -> tolower: z
元の文字: 9 -> toupper: 9

ソースコードの解説

まず、#include <ctype.h> を記述して、文字操作用のライブラリを読み込んでいます。

toupper 関数は、引数として渡された文字が「小文字のアルファベット」であれば、対応する「大文字」を返します。
もし最初から大文字であったり、記号や数字であったりする場合は、変換せずに元の文字をそのまま返します。

tolower 関数も同様に、大文字であれば小文字に変換し、それ以外はスルーします。
この「アルファベットかどうかの判定」を内部でやってくれる点が、標準関数の最大のメリットです。

また、これらの関数はロケール(言語設定)に依存します。

例えばトルコ語ロケールなどでは、英語圏とは異なる変換規則が適用される場合がありますが、一般的な英語環境や “C” ロケールではASCII範囲の変換が行われます。

文字列全体を一括で大文字・小文字に変換する

標準の touppertolower は「1文字」しか処理できません。

文字列(char配列)全体を変換したい場合は、ループ処理を使って一文字ずつ変換していく必要があります。

文字列変換の自作関数サンプル

文字列を渡すと、その内容をすべて大文字(または小文字)に書き換える関数を作成してみましょう。

#include <stdio.h>
#include <ctype.h>

// 文字列をすべて大文字に変換する関数
void to_upper_string(char *str) {
    // 文字列の終端(\0)が来るまでループ
    for (int i = 0; str[i] != '\0'; i++) {
        // 各文字を大文字に変換して上書き
        // ここでも (unsigned char) へのキャストを行う
        str[i] = toupper((unsigned char)str[i]);
    }
}

int main(void) {
    // 【重要】書き換え可能な配列として宣言する
    // char *text = "Hello..."; とすると書き換え時にエラーになる可能性がある
    char text[] = "Hello, C Language!";

    printf("変換前: %s\n", text);

    to_upper_string(text);

    printf("変換後: %s\n", text);

    return 0;
}

実行結果

変換前: Hello, C Language!
変換後: HELLO, C LANGUAGE!

ソースコードの解説

to_upper_string 関数では、受け取ったポインタ str を使って配列の各要素にアクセスしています。

for 文の中で str[i] がヌル文字 \0 になるまでループを回し、一文字ずつ toupper 関数に通しています。
変換した結果を str[i] = ... で元の場所に代入し直すことで、文字列自体を書き換えています。

【注意点】
 main 関数内での文字列宣言に char text[] = "..." を使用しているのは重要です。
もし char *text = "..."(文字列リテラルへのポインタ)として宣言した場合、そのメモリ領域は書き換え禁止(Read-Only)である可能性が高く、変換しようとするとプログラムが異常終了することがあります。

ASCIIコードの計算(+32, -32)で変換する方法

標準関数を使わずに、数値計算だけで変換を行うことも可能です。

C言語における文字(char)は、内部的には ASCIIコード という整数値で管理されているため、足し算や引き算で文字を変えることができます。

ASCIIコードの仕組みと変換ロジック

ASCIIコード表を見ると、アルファベットの大文字と小文字は、規則正しく並んでいることがわかります。

  • ‘A’ (65) ~ ‘Z’ (90)
  • ‘a’ (97) ~ ‘z’ (122)

この数値を見比べると、小文字は対応する大文字よりも常に 32 だけ大きい値になっています(例:97 – 65 = 32)。

つまり、以下の計算式が成り立ちます。

  • 大文字にする: 小文字の値から 32 を引く
  • 小文字にする: 大文字の値に 32 を足す

ただし、実務でコードを書く際は「32」という数字(マジックナンバー)を直接書くよりも、'a' - 'A' のように書くほうが、「大文字と小文字の差分である」という意図が明確になり推奨されます。

計算による変換のサンプルコード

#include <stdio.h>

int main(void) {
    char lower = 'b';
    char upper = 'Y';
    
    // 大文字と小文字の差分(32)を計算で求める
    // これによりマジックナンバーを避けられる
    const int case_diff = 'a' - 'A';

    // 小文字を大文字に変換(差分を引く)
    // 必ず小文字であることを確認してから計算する必要がある
    if (lower >= 'a' && lower <= 'z') {
        lower = lower - case_diff;
    }

    // 大文字を小文字に変換(差分を足す)
    if (upper >= 'A' && upper <= 'Z') {
        upper = upper + case_diff;
    }

    printf("変換後 lower: %c\n", lower);
    printf("変換後 upper: %c\n", upper);

    return 0;
}

実行結果

変換後 lower: B
変換後 upper: y

ソースコードの解説

変数 lower には ‘b’ (98) が入っています。
ここから差分(32)を引くと 66 となり、これは ‘B’ のASCIIコードと一致します。

変数 upper には ‘Y’ (89) が入っています。
これに差分(32)を足すと 121 となり、これは ‘y’ と一致します。

重要なのは if (lower >= 'a' && lower <= 'z') のような判定を入れている点です。

これを行わずに単に足し引きをしてしまうと、記号や数字が全く別の文字に化けてしまうため、標準関数を使わない場合は自力での範囲チェックが必須となります。

大文字・小文字を区別しない比較について

変換処理の応用としてよくあるのが、「大文字・小文字を区別せずに文字列を比較したい」というケースです。
例えば、ユーザーが “YES” と入力しても “yes” と入力しても同じように扱いたい場合などです。

標準の strcmp 関数は文字コードを厳密に比較するため、”A” と “a” は別物と判断されます。
このような場合は、比較する両方の文字列を一度 toupper(または tolower)で揃えてから比較するのが定石です。

環境によっては専用の比較関数が用意されていることもありますが、規格によって名前が異なるため注意が必要です。

  • strcasecmp: POSIX標準(Linux, macOSなど)
  • _stricmp: Microsoft独自拡張(Windowsなど)

移植性(どの環境でも動くこと)を重視する場合は、自分で変換してから strcmp を行う方法が最も確実です。

C言語のスキルを活かして年収を上げる方法

以上、C言語で大文字と小文字を変換する方法や、toupper/tolower関数の使い方、ASCIIコードの計算ロジックなどについて解説してきました。

なお、C言語のスキルがある場合には、「転職して年収をアップさせる」「副業で稼ぐ」といった方法を検討するのがおすすめです。

C言語を扱えるエンジニアは比較的希少価値が高く、転職によって数十万円の年収アップはザラで、100万円以上年収が上がることも珍しくありません。

なお、転職によって年収を上げたい場合は、エンジニア専門の転職エージェントサービスを利用するのが最適です。

今すぐ転職する気がなくとも、とりあえず転職エージェントに無料登録しておくだけで、スカウトが届いたり、思わぬ好待遇の求人情報が送られてきたりするというメリットがあります。

併せて、副業案件を獲得できるエージェントにも登録しておくと、空いている時間を活かして稼げるようなC言語の案件を探しやすくなります。

転職エージェントも副業エージェントも、登録・利用は完全無料なので、どんな求人や副業案件があるのか気になる方は、気軽に利用してみるとよいでしょう。