C言語 文字列処理の復習
C言語の文字と文字列を復習してみる
文字
C言語で文字型はchar型というデータ型で1バイトのメモリサイズをもつ。
int main(void) { char x; x = 'a'; printf("%c\n", x); return 0; }
出力結果
a
プログラム中の'a'は「aという文字」を表すchar型定数。1バイト文字でないと駄目。
日本語は2バイト文字の為char型定数にはならない。
文字列
C言語には文字列型という型はなくchar型の配列で表される。その配列は「文字列の最後に
終端を表す'\0'(ヌル文字)がついている」という約束を守っている必要がある。
#include <stdio.h> #include <string.h> int main(void) { char mojiretu[] = "ABCDEFGHIJ"; printf("strlen %zd\n", strlen(mojiretu)); printf("sizeof %ld\n", sizeof(mojiretu)); return 0; }
出力結果
strlen 10 ※文字列長は10
sizeof 11 ※文字列サイズは11
終端記号として'\0'が付加されているためサイズは11になる。
⇒ダブルクォーテーションで囲まれた文字列には自動的に\0が付加される
char mojiretu[] = "ABCDEFGHIJ"は
char mojiretu2[11]={"ABCDEFGHIJ"と同じ意味になる。
(char mojiretu[11]={'A','B','C','D','E','F','G','H','I','J','\0'}とも同じ)
配列の宣言時には\0のメモリを確保しないといけないので
最低でも確保する文字数+1の要素数が必要。
文字列をコピーする場合(標準ライブラリ関数を使用しない場合)
配列の中身を一文字ずつコピーして最後に\0を付ければよい
#include <stdio.h> int main(void) { char mojiretu[] = "ABCDEFGHIJ"; char cpmojiretu[11]; int i; printf("mojiretu:%s\n", mojiretu); while(mojiretu[i] != '\0') { cpmojiretu[i] = mojiretu[i]; i++; } cpmojiretu[i] = '\0'; printf("コピー後の文字列:%s\n", cpmojiretu); return 0; }
文字列処理の標準ライブラリ関数
strcpy 文字列のコピー
終端文字までコピーされる
#include <stdio.h> #include <string.h> int main(void) { char mojiretu[] = "ABCDEFGHIJ"; char cpmojiretu[11]; printf("mojiretu:%s\n", mojiretu); strcpy(cpmojiretu, mojiretu); printf("copyされた文字:%s\n", cpmojiretu); return 0; }
出力結果
mojiretu:ABCDEFGHIJ
copyされた文字:ABCDEFGHIJ
strncpy 文字列のコピー(文字数制限あり)
終端文字はコピーされないので自分で付ける必要がある
int main(void) { char mojiretu[] = "ABCDEFGHIJ"; char cpmojiretu[6]; printf("mojiretu:%s\n", mojiretu); strncpy(cpmojiretu, mojiretu, 5); cpmojiretu[5] = '\0'; printf("copyされた文字:%s\n", cpmojiretu); return 0; }
strncpyで終端文字を入れなかった場合
#Include <stdio.h> #include <string.h> int main(void) { /* コピーする文字列 */ char mojiretu[] = "Afro-Blue"; /* コピー先文字列 */ char cpmojiretu[4]; strncpy(cpmojiretu, mojiretu, sizeof(cpmojiretu)); printf("%s\n", cpmojiretu); printf("mojiretu: strlen %2zd sizeof %2ld %p\n", strlen(mojiretu), sizeof(mojiretu), mojiretu); printf("cpmojiretu: strlen %2zd sizeof %2ld %p\n", strlen(cpmojiretu), sizeof(cpmojiretu), cpmojiretu); return 0; }
出力結果
AfroAfro-Blue
mojiretu: strlen 9 sizeof 10 0x7fff6e813aee
cpmojiretu: strlen 13 sizeof 4 0x7fff6e813aea
cpmojiretuに最大4文字分コピーされるが終端文字がないため、直後の配列mojiretuの
値も表示している。
⇒cpmojiretuが0x7fff6e813aeaにあって4文字分(0x....aedまで)コピーされている
そのとなり(0x....aee)にmojiretuがあるため、mojiretuの内容まで表示されている
strncpyでコピーした文字列は最後に終端文字(\0)を入れないといけない。
strcmp 文字列の比較
strcmp(A, B)は文字列を比較して等しいときには0、Aが小さいときは負の値、Aが大きいときは正の値を返す。
int main(void) { char mojiretu[] = "ABCDEFGHIJ"; char mojiretu2[11]={"ABCDEFGHIJ"}; cmp = strcmp(mojiretu, mojiretu2); if (strcmp(mojiretu, mojiretu2) == 0) { printf("Equal\n"); } else { printf("Not Equal\n"); } return 0; }
出力結果
Equal
strncmp 文字列の比較(文字数制限あり)
これは文字数指定のあるstrcmp。内容は省略。
strchr 文字列中で文字を探しそのポインタを返却
int main(void) { int cmp; char mojiretu[] = "ABCDEFGHIJ"; char *p; p = strchr(mojiretu, 'F'); printf("'F'以降の文字:%s\n", p); return 0; }
出力結果
'F'以降の文字:FGHIJ
strstr 文字列中で部分文字列を探しそのポインタを返却
int main(void) { int cmp; char mojiretu[] = "ABCDEFGHIJ"; char search[] = "EFG"; char *p; p = strstr(mojiretu, search); printf("文字列EFG以降の文字:%s\n", p); }
出力結果
文字列EFG以降の文字:EFGHIJ