C言語:文字と文字列

| トラックバック(0)
※C言語初心者の為、内容に不備がある可能性があります。

C言語での文字の取り扱いについて。

文字を変換指定子「%c」と「%d」で出力してみる。


#include <stdio.h>

int main() {
  char a1, a2, a3;

  a1 = 'a';
  a2 = 'b';
  a3 = 'c';
  printf( "%c%c%c\n", a1, a2, a3 );
  printf( "a1 = %d, a2 = %d, a3 = %d\n", a1, a2, a3 );
  return 0;
}

実行結果
abc
a1 = 97, a2 = 98, a3 = 99

%dで出力してもコンパイルエラーも無くコンパイルが終わり、実行できた。
結果を見てみると「%d」での出力は数字になっている。
この数字はどうもASCIIコードを表しているみたい。
文字は単なる数字ということらしい。

文字は数字ということを利用してこんなこと↓もできるらしい。
#include <stdio.h>
int main() {
  char i;

  for( i = '!'; i <= '~'; i++ ) {
    printf( "%3d(0x%2X) -- %c ", i, i, i );
    if( ( i - '!' + 1 ) % 4 == 0 )
      printf( "\n" );
  }
  printf( "\n" );
  return 0;
}


実行結果
$ ./char03.exe 
 33(0x21) -- !  34(0x22) -- "  35(0x23) -- #  36(0x24) -- $ 
 37(0x25) -- %  38(0x26) -- &  39(0x27) -- '  40(0x28) -- ( 
 41(0x29) -- )  42(0x2A) -- *  43(0x2B) -- +  44(0x2C) -- , 
 45(0x2D) -- -  46(0x2E) -- .  47(0x2F) -- /  48(0x30) -- 0 
 49(0x31) -- 1  50(0x32) -- 2  51(0x33) -- 3  52(0x34) -- 4 
 53(0x35) -- 5  54(0x36) -- 6  55(0x37) -- 7  56(0x38) -- 8 
 57(0x39) -- 9  58(0x3A) -- :  59(0x3B) -- ;  60(0x3C) -- < 
 61(0x3D) -- =  62(0x3E) -- >  63(0x3F) -- ?  64(0x40) -- @ 
 65(0x41) -- A  66(0x42) -- B  67(0x43) -- C  68(0x44) -- D 
 69(0x45) -- E  70(0x46) -- F  71(0x47) -- G  72(0x48) -- H 
 73(0x49) -- I  74(0x4A) -- J  75(0x4B) -- K  76(0x4C) -- L 
 77(0x4D) -- M  78(0x4E) -- N  79(0x4F) -- O  80(0x50) -- P 
 81(0x51) -- Q  82(0x52) -- R  83(0x53) -- S  84(0x54) -- T 
 85(0x55) -- U  86(0x56) -- V  87(0x57) -- W  88(0x58) -- X 
 89(0x59) -- Y  90(0x5A) -- Z  91(0x5B) -- [  92(0x5C) -- \ 
 93(0x5D) -- ]  94(0x5E) -- ^  95(0x5F) -- _  96(0x60) -- ` 
 97(0x61) -- a  98(0x62) -- b  99(0x63) -- c 100(0x64) -- d 
101(0x65) -- e 102(0x66) -- f 103(0x67) -- g 104(0x68) -- h 
105(0x69) -- i 106(0x6A) -- j 107(0x6B) -- k 108(0x6C) -- l 
109(0x6D) -- m 110(0x6E) -- n 111(0x6F) -- o 112(0x70) -- p 
113(0x71) -- q 114(0x72) -- r 115(0x73) -- s 116(0x74) -- t 
117(0x75) -- u 118(0x76) -- v 119(0x77) -- w 120(0x78) -- x 
121(0x79) -- y 122(0x7A) -- z 123(0x7B) -- { 124(0x7C) -- | 
125(0x7D) -- } 126(0x7E) -- ~ 

上記は"!"?"~"までのASCIIコードを表示するプログラム。
forの部分は
for( i = 33; i <= 126; i++ ) {
と書いても同じこと。
次に文字をint型で扱ってみる。
#include <stdio.h>

int main() {
  int c;

  for( c = 'A'; c <= 'z'; c++ ) {
    if( (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') )
      printf( "%c = %3d(0x%X)\n", c, c, c );
  }
  return 0;
}

実行結果
$ ./char04.exe 
A =  65(0x41)
B =  66(0x42)
C =  67(0x43)
D =  68(0x44)
E =  69(0x45)
F =  70(0x46)
G =  71(0x47)
H =  72(0x48)
I =  73(0x49)
J =  74(0x4A)
K =  75(0x4B)
L =  76(0x4C)
M =  77(0x4D)
N =  78(0x4E)
O =  79(0x4F)
P =  80(0x50)
Q =  81(0x51)
R =  82(0x52)
S =  83(0x53)
T =  84(0x54)
U =  85(0x55)
V =  86(0x56)
W =  87(0x57)
X =  88(0x58)
Y =  89(0x59)
Z =  90(0x5A)
a =  97(0x61)
b =  98(0x62)
c =  99(0x63)
d = 100(0x64)
e = 101(0x65)
f = 102(0x66)
g = 103(0x67)
h = 104(0x68)
i = 105(0x69)
j = 106(0x6A)
k = 107(0x6B)
l = 108(0x6C)
m = 109(0x6D)
n = 110(0x6E)
o = 111(0x6F)
p = 112(0x70)
q = 113(0x71)
r = 114(0x72)
s = 115(0x73)
t = 116(0x74)
u = 117(0x75)
v = 118(0x76)
w = 119(0x77)
x = 120(0x78)
y = 121(0x79)
z = 122(0x7A)


次に文字列。
ABCのような文字の並びを文字列といい、ダブルクォーテーションで囲む。
"ABC"を文字列リテラルと言う。
"ABC"がメモリに置かれる場合、'A'、 'B'、 'C'の順にメモリ上に置かれる。
そして'C'の次には'\0'(ヌル文字)が置かれる。
ヌル文字は文字列がここで終わりという合図を示す。

以下イメージ図
________________
|     |      |       |      |
|A   | B  | C    | \0  |
|___|___|____|___|
300  301 302 303  <- アドレス

んで、"ABC"の式は配列のときと同様に'A'の置かれたアドレスを指す。
「文字列の式の値は、先頭文字の置かれたアドレス」


 

char型のポインタへ代入してみる。
#include <stdio.h>
int main() {
  char *str;
  str = "ABC";
  printf(
         "*(str + 0) = '%c', "
         "*(str + 1) = '%c', "
         "*(str + 2) = '%c'\n",
         *(str + 0), *(str + 1), *(str + 2)
         );
  printf( "str[0] = '%c', str[1] = '%c', str[2] = '%c'\n",
          str[0], str[1], str[2]);
  return 0;
}

実行結果
*(str + 0) = 'A', *(str + 1) = 'B', *(str + 2) = 'C'
str[0] = 'A', str[1] = 'B', str[2] = 'C'


文字列の内容を比較する(strcmp関数
#include <stdio.h>
#include <string.h> /* strcmp関数を使うため */

int main() {
  char str1[32], str2[32];
  int cmp;
  printf( "str1を入力してください---" );
  scanf( "%s", str1 );
  printf( "str2を入力してください---" );
  scanf( "%s", str2 );

  cmp = strcmp( str1, str2 );
  if( cmp < 0 )
    printf( "%sは、%sより前にあります\n", str1, str2 );
  else if( cmp > 0 )
    printf( "%sは、%sより後ろにあります\n", str1, str2 );
  else
    printf( "%sと%sは、同じ文字列です\n", str1, str2 );

  return 0;
}

実行結果
$ ./string03.exe 
str1を入力してください---asd
str2を入力してください---asd
asdとasdは、同じ文字列です
$ ./string03.exe 
str1を入力してください---asd
str2を入力してください---asf
asdは、asfより前にあります
$ ./string03.exe 
str1を入力してください---asf
str2を入力してください---asd
asfは、asdより後ろにあります

strcmp関数は辞書式に並べたときに前にあればマイナス、後ろにあればプラスを、
まったく同じであれば0を返すらしい。

そのほかに文字列の長さを調べる「strlen」関数もある。

猫でもわかるC言語プログラミング 第2版 猫でもわかるプログラミングシリーズ (NEKO Series)
粂井 康孝
ソフトバンククリエイティブ
売り上げランキング: 4362
おすすめ度の平均: 3.0
3 後半の説明に難あり?
5 猫でもわかるC言語プログラミング
1 猫どころか人間でもわからない
5 実際にコードを書いて覚える本
1 ポインタや配列の説明が内容的に薄いかな。

トラックバック(0)

トラックバックURL: http://www.mogumagu.com/mt/mt-tb.cgi/14

2012年1月

1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        

ウェブページ

このブログ記事について

このページは、モグマグが2010年4月23日 23:59に書いたブログ記事です。

ひとつ前のブログ記事は「C言語:配列」です。

次のブログ記事は「Google App Engine の Python用開発環境を設定してみる。」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

Powered by Movable Type 5.01