C言語には、文字列を処理するための様々な関数が用意されています。
それらをうまく使うことで、文字列を自由に処理できます。
atoi関数は、文字列を数値に変換した結果を変数に代入します。
atoi関数の使い方は次の通りです。
なお、atoi関数を使うには、stdlib.h を #include する必要があります。
次のプログラムは、atoi関数を使って数値を変換する例です。変数 = atoi(文字列配列名);
このプログラムの実行結果は次の通りになります。#include <stdio.h> #include <stdlib.h> int main(void) { char str[] = "145"; int suuti = atoi(str); printf("%d\n",suuti); return 0; }
atoi関数では、+-の付いた符号付きの数字も変換できます。
145
strcpy関数を使うと、文字列のコピーを行うことが出来ます。
strcpy関数の使い方は次の通りです。
なお、strcpy関数を使うには、string.h を #include する必要があります。
この関数は、文字列配列同士のコピーに使うのが元々の役目なのですが、strcpy(コピー先文字列配列名,コピー元文字列配列名);
このプログラムの実行結果は次の通りになります。#include <stdio.h> #include <string.h> int main(void) { char str[10]; strcpy(str,"MARIO"); printf("%s\n",str); return 0; }
前章の最後で、1つずつ代入する方法を説明しましたが、こちらのほうが簡単です。
MARIO
さらに、先頭から指定された文字数だけをコピーするstrncpy関数もあります。
strncpy関数の使い方は次の通りです。
この関数は、文字数の分だけコピーするだけなので、strncpy(コピー先文字列配列名,コピー元文字列配列名,コピーする文字数);
次のプログラムは、文字列の先頭から3文字を取り出して表示する例です。strncpy(コピー先文字列配列名,コピー元文字列配列名,コピーする文字数); コピー先文字列配列名[コピーする文字数] = '\0';
このプログラムの実行結果は次の通りになります。#include <stdio.h> #include <string.h> int main(void) { char str1[] = "MARIO",str2[10]; strncpy(str2,str1,3); str2[3] = '\0'; /* EOSを付加 */ printf("%s\n",str2); return 0; }
MAR
[ strncpyは危険 ]
strncpy関数では必ずEOSを付けなくてはならないのですが、
それを忘れてしまいそうな人は、EOSを付ける関数を作るべきです。
なお、配列を関数に渡す方法は後に説明します。
文字列リテラルを連結するだけなら関数は必要ありません。
文字列リテラルをただ並べるだけで連結されるからです。
次のプログラムは、文字列リテラルの連結を行う例です。
このプログラムの実行結果は次の通りになります。#include <stdio.h> int main(void) { char str[] = "DRAGON" "QUEST"; printf("%s\n",str); return 0; }
DRAGON と QUEST が連結されていることがわかると思います。
DRAGONQUEST
ただし、配列に記憶された文字列を連結する場合には、配列名を並べても駄目です。
その場合はstrcat関数を使います。strcat関数の使い方は次の通りです。
なお、strcat関数を使うには、string.h を #include する必要があります。
次のプログラムは、strcat関数を使って文字列を連結する例です。strcat(元の文字列が記憶された配列,追加する文字列の記憶された配列);
このプログラムの実行結果は次の通りになります。#include <stdio.h> #include <string.h> int main(void) { char str1[12] = "DRAGON"; char str2[] = "QUEST"; strcat(str1,str2); printf("%s\n",str1); return 0; }
この関数を使う時に注意してほしいのは、元の文字列が記憶された配列は、
DRAGONQUEST
ここで、究極の文字列合成関数を紹介したいと思います。
筆者が調べた限りではほとんどの入門書ではこの関数が紹介されていないのですが、
この関数はあらゆる文字列合成に使用できる万能関数なので是非覚えるべきです。
sprintf関数は、printf関数と同じ機能を持った関数ですが、
sprintf関数の場合、結果を配列の中に記憶します。
printf関数の様々な機能を自由に取り扱うことが出来るのです。
sprintf関数の使い方は次の通りです。
なお、sprintf関数を使うには、string.h を #include する必要があります。
次のプログラムは、sprintf関数を使う例です。sprintf(結果を記憶する配列,書式文字列,各種変数・・・);
このプログラムの実行結果は次の通りになります。#include <stdio.h> #include <string.h> int main(void) { char str[16]; char str1[12] = "DRAGON"; char str2[] = "QUEST"; int i = 3; sprintf(str,"%s%s%d\n",str1,str2,i); printf(str); return 0; }
この関数を使えば、ほとんどの文字列合成が実現できます。
DRAGONQUEST3
[ 直に文字配列 ]
先ほどのプログラムでは文字列の表示に、
と、%s指定子を使用せずに直接文字配列 str を渡しています。printf(str);
そもそも printf関数は文字列を表示する関数なので、
わざわざ %s指定子を使わなくても表示できるのです。
ただし、文字列中に % が含まれていると、
出力変換指定子と誤解して誤動作するので、その時は %s を用います。
数値と同様、文字列を入力する場合にもscanf関数を使うことが出来ます。
文字列を入力する場合、scanf関数で%s指定子を指定します。
ただし、配列名の前に&を付けません。
次のプログラムは、入力した文字列をそのまま表示する例です。
このプログラムの実行結果は、次の通りになります。#include <stdio.h> int main(void) { char str[32]; scanf("%s",str); printf("%s\n",str); return 0; }
これで、自由に文字列を入力することが出来ますが、注意点があります。
MARIO キーボードから入力した文字列
MARIO
1つ目は、配列の要素数よりも多く入力すると暴走してしまうことです。
これが、第6章でも説明した入力ミスの恐怖なのです。
この問題を解決するには、文字配列の要素数を%とsの間で指定します。
例えば、要素数が32の場合は%32sと指定すると、それ以上の文字は切り捨てられます。
次のプログラムは、文字列の切り捨ての例です。
このプログラムの実行結果は、次の通りになります。#include <stdio.h> int main(void) { char str[32]; scanf("%32s",str); printf("%s\n",str); return 0; }
文字列は途中までですが、暴走は防がれており、安全になっています。
0123456789012345678901234567890123456789 キーボードから入力した文字列
01234567890123456789012345678901
2つ目は、この方法では、スペースを入力できないことです。
これは、スペースが区切り記号として認識されるためです。
残念ながら、こちらの解決は困難です。
文字列の数を数えるのは難しいことではありません。
文字配列の先頭からEOSが出現するまでの数を数えるだけのことです。
次のプログラムは、入力された文字列の数を表示する例です。
このプログラムの実行結果は、次の通りになります。#include <stdio.h> int main(void) { int i; char str[256]; scanf("%s",str); for (i = 0;str[i] != '\0';i++); printf("%d\n",i); return 0; }
for文の意味が少しわかりにくいかも知れませんが、
ABCDEF キーボードから入力した文字列
6
ただ、文字列の文字数を数えるために毎回for文を書くのは面倒です。
そのため、文字列の文字数を数えるstrlen関数が用意されています。
なお、strlen関数を使うには、string.h を #include する必要があります。
次のプログラムは、先ほどのプログラムをstrlen関数で書き直した例です。変数 = strlen(文字配列);
実行結果は先ほどと同じになります。#include <stdio.h> #include <string.h> int main(void) { int i; char str[256]; scanf("%s",str); i = strlen(str); printf("%d\n",i); return 0; }
文字配列の内容が同じかを比較する場合、次のようなプログラムを考えると思います。
しかし、文字配列同士の比較では==演算子を使うことは出来ません。str1 == str2;
文字配列の中身を比較するにはfor文で全要素を比較する必要があります。
次のプログラムは、入力された文字列が DRAGONQUEST であるかどうかを比較する例です。
このプログラムの実行結果は、次の通りになります。#include <stdio.h> #include <string.h> int main(void) { int len,i; char str1[256],str2[] = "DRAGONQUEST"; scanf("%s",str1); len = strlen(str2); for (i = 0;i < len + 1;i++) { if (str1[i] != str2[i]) break; } if (i == len + 1) { printf("同じ\n"); } else { printf("違う\n"); } return 0; }
DRAGONQUEST キーボードから入力した文字列
同じ
ABCDEF キーボードから入力した文字列
違う
文字列の比較ではEOSまでが同じでなければならないため、
DRAGONQUEST3 キーボードから入力した文字列
違う
ただ、文字列の文字数を数えるために毎回for文を書くのは面倒です。
そのため、文字列を比較するstrcmp関数が用意されています。
なお、strcmp関数を使うには、string.h を #include する必要があります。
この関数は、2つの文字配列の中身が同じである場合には0を返します。変数 = strcmp(文字配列1,文字配列2);
実行結果は先ほどと同じになります。#include <stdio.h> #include <string.h> int main(void) { char str1[256],str2[] = "DRAGONQUEST"; scanf("%s",str1); if (strcmp(str1,str2) == 0) { printf("同じ\n"); } else { printf("違う\n"); } return 0; }