苦しんで覚える C言語

苦しんで覚える
C言語

文字の扱い方

文字列を扱う変数
これまで、プログラム中で何回も文字列を扱ってきたのですが、
なぜか、文字列を記憶する変数は1度も説明したことがありませんでした。
その理由は簡単です。C言語には文字列を記憶する変数がないからです。

文字列用の変数がないのは、文字列が特殊な性質を持つためです。
文字列は、何文字になるのかが事前に予測できません。
5文字程度で済むこともあれば、何千文字という文字数になることもあります。
この様に、場合によって必要とされるメモリのサイズが異なってくるのです。

この様な事情があるため、C言語には文字列用の変数がありません。

他の言語では
C言語以外のプログラミング言語では、次のような構造で文字列変数を用意しています。

1、メモリを固定的に確保(メモリ消費量のムダが多くなるが、高速で扱いやすい)
2、メモリを可変的に確保(メモリ消費量を減らせるが、低速。)

このように、どちらも一長一短となっており、向き不向きがあります。
C言語では、プログラマーが自由な方法で文字列を表現できるようになっています。

文字を扱うには
前項では、C言語には、文字列変数はないと書きましたが、
文字列変数はなくても、文字変数であれば用意されています。
文字列と違い、文字は必ず1文字であるため、変数で扱うことができるのです。

C言語では、文字変数として、char(キャラ)型が用意されています。
char型の変数には、1文字を記憶しておくことができます。
文字は '' で囲むことで表現します。

また、%c指定子を使えば、printf関数で表示できます。
次のプログラムは、char型の変数に文字を記憶して表示する例です。

ソースコード
#include <stdio.h>

int main(void)
{
    char c = 'A';
    printf("%c\n", c);
    return 0;
}

このプログラムの実行結果は、次の通りになります。

実行結果
A

この様に、char型を使えば、文字を変数と同様に取り扱うことが可能です。

全角文字は駄目
実は、この方法では、全角文字を扱うことはできません。
char型で記憶できる文字の種類は最大で255種類が限界で、
何千文字もある日本語の文字を記憶しておくことは出来ないのです。

この問題を解決する手段として、wchar_t型が用意されているのですが、
まずは基本の文字変数をしっかり覚えてほしいので、ここでは扱いません。

文字コード
前項では、char型で1文字を取り扱うことができることを説明しましたが、
これは、コンピュータで使われる文字コードの仕組みを利用しています。

キーワード
【文字コード】

コンピュータで使われる文字に1対1で対応する番号をつけて表現する方法。
ASCIIコードという規格では半角のアルファベットや記号が割り当てられている。
日本語を扱えるコードとして、JIS、シフトJIS、EUCが使われている他、
世界中の言語を扱えるコードとして Unicode が普及している。


文字コードとは、文字に1対1で対応する番号をつけて表現する方法のことです。
次の表は、半角文字の番号表としてもっとも使われている規格であるASCIIコードの例です。

番号 番号(16進数) 文字
62 0x3e
63 0x3f ?
64 0x40 @
65 0x41 A
66 0x42 B
67 0x43 C
68 0x44 D
97 0x61 a
98 0x62 b


この表を丸暗記しようとしないでください
こういった表を出すと、受験勉強のように丸暗記しようとする人が出てくるのですが、
暗記する必要はまったくありません。もちろん筆者も暗記しておりません。
実はAが65くらいは覚えていたりしますが・・・
重要なことは、文字には番号がついているという仕組みあり、番号そのものではありません

char型変数に文字を代入するのは、この番号を代入しているだけのことです。
つまり、実のところ、char型は普通の整数型とまったく同じなのです。

たとえば、前項のプログラムでは、'A' をchar型変数cに代入しましたが、
これは、A が65番に割り当てられているので、コンパイラが 'A' を 65 と解釈し、
その65がcに代入されただけのことに過ぎません。

また、printf関数で A が表示されたのも、変数の中身が65だったので、
printf関数の方で A と表示するように処理しただけのことなのです。

つまり、コンピュータではすべての文字は番号で表されており、
char型はその番号を記憶しておくに過ぎないということなのです。
文字に対する計算
char型で記憶されている文字は、実は単なる番号であることを前項で説明しましたが、
このことを利用すれば、文字に対して計算を行うこともできます。

たとえば、文字コードでは、基本的に文字の番号は順番通りに定義されています。
半角アルファベットでは、A が65、Bが66、Cが67、のように決められています。
つまり、Aに足し算を行うと、何番目のアルファベットの文字を取り出すことができます。
次のプログラムは、10番目のアルファベットを取り出す例です。

ソースコード
#include <stdio.h>

int main(void)
{
    char c = 'A' + 9; /* 最初は0なので9を足す */
    printf("%c¥n", c);
    return 0;
}

このプログラムの実行結果は、次の通りになります。

実行結果
J


数字を使う時には、引き算で本来の数値を知ることもできます。
数字にも文字の番号が割り当てられており、たとえば '0' は48番に割り当てられています。
数字から '0' の番号を引き算すれば、数値に変換され計算に使用できます。
次のプログラムは、数字を数値に変換する例です。

ソースコード
#include <stdio.h>

int main(void)
{
    char c = '8'; /* 数字 */
    int suuti = c - '0'; /* 数値に変換 */
    printf("%d\n",suuti);
    return 0;
}

このプログラムの実行結果は、次の通りになります。

実行結果
8


このプログラムでは、数値に変換した結果を%d指定子で表示させています。

ただし、先ほどのプログラムの問題点は、数字以外の文字も変換されることです。
たとえば、'A' は65番なので、'A' を数値に変換させると17になってしまいます。
この問題を解決するには、変換する文字が数字であるかを判定する必要があります。

これは比較的簡単です。文字の番号が、'0' ~ '9' の間にあるか調べるだけです。
次のプログラムは、数字を数値に変換し、数字以外はすべて0に変換する例です。

ソースコード
#include <stdio.h>

int main(void)
{
    char c = 'A'; /* 数字 */
    int suuti;

    if (c >= '0' && c <= '9' ) {
        /* 判定部分 */ 
        suuti=c - '0' ; /* 数値に変換 */ 
    } else {
        suuti=0; 
    }

    printf("%d\n",suuti); return 0;
} 

このプログラムの実行結果は、次の通りになります。

実行結果
0


もちろん、数字を指定した場合には、ちゃんと数値に変換されます。
ある文字が数値かどうかを調べる方法は、アルファベットにも応用できます。
ただし、大文字の 'Z' から小文字の 'a' には連続していないので、
'A' ~ 'Z' と 'a' ~ 'z' をそれぞれ調べる必要があります。

また、これらの機能は関数化されており、次の関数が使えます。
なお、これらの関数の使用には、ctype.h を #include する必要があります。

名前 文字種類 文字一覧
isalnum 英数字 A~Z a~z 0~9
isdigit 10進数 0~9
isxdigit 16進数 A~F a~f 0~9
isalpha 英字 A~Z a~z
isupper 英大文字 A~Z
islower 英小文字 a~z
ispunct 記号 !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
isspace スペース 0x09~0x0D 0x20

次のプログラムは、isdigit関数を使って先ほどのプログラムを書き換えた例です。

ソースコード
#include <stdio.h>
#include <ctype.h>

int main(void)
{
    char c = 'A';
    int suuti;

    if (isdigit(c)) { 
        /* 判定部分 */
        suuti = c - '0';
    } else {
        suuti = 0;
    }

    printf("%d\n",suuti);
    return 0;
}

実行結果は、先ほどまったく同じになります。

実行結果
0



本サイトについて

苦しんで覚えるC言語(苦C)は
C言語入門サイトの決定版です。
C言語の基本機能を体系立てて解説しており、
市販書籍と同等以上の完成度です。

第0部:プログラム概要編
  1. プログラムとは何か?
2章:プログラムの書き方
  1. 書き方のルール
  2. 書き方の慣習
  3. 練習問題2
3章:画面への表示
  1. 文字列の表示
  2. 改行文字
  3. 練習問題3
6章:キーボードからの入力
  1. 入力用の関数
  2. 入力の恐怖
  3. 練習問題6
9章:回数が決まっている繰り返し
  1. 繰り返しを行う文
  2. ループ動作の仕組み
  3. 練習問題9
10章:回数がわからない繰り返し
  1. 回数不明ループ
  2. 入力チェック
  3. 練習問題10
13章:複数の変数を一括して扱う
  1. 複数の変数をまとめて扱う
  2. 配列の使い方
  3. 練習問題13
20章:複数のソースファイル
  1. 最小限の分割
  2. 分割の定石
  3. 練習問題20
コメントシステムを読込中・・・