当日のOHP資料です。
9.文字列の基本( Text p.207 - 223 )
-->
Download : sample-001.c ( SJIS 版 )
/* * 文字列の配列への読み込み (scanf/gets は危険) */ #include <stdio.h> /* * main */ #define PASS_LEN 4 /* 鍵の長さ */ #define PASS_SIZE (PASS_LEN)+1 /* 鍵を納める配列のサイズ(長さ+1) */ #define ARY_SIZE 2 #define LOCK 1 /* 錠 */ #define KEY 0 /* 鍵 */ #define ever (;;) int main ( void ) { char str_ary[ARY_SIZE][PASS_SIZE]; int i; printf ( "鍵をかける 4 文字長さのパスワードを入力してください : " ); scanf ( "%s", str_ary[LOCK] ); /* 危険 !! */ for ever { /* 鍵が開くまで、ずっと周る */ printf ( "\n現在、鍵がかかっています\n" ); printf ( "鍵を開けるためのパスワードを入力してください : " ); scanf ( "%s", str_ary[KEY] ); /* 危険 !! */ for ( i = 0; i < PASS_LEN; i++ ) { /* パスワードチェック */ if ( str_ary[KEY][i] != str_ary[LOCK][i] ) { /* 違っている部分がある !! */ break; /* 後は調べる必要なし */ } } if ( i < PASS_LEN ) { /* 途中までしか調べてなければ、一致しなかった */ printf ( "パスワードが一致していません !!!\n" ); } else { /* そうでなければ、一致したので.. */ printf ( "パスワードが一致しました\n" ); break; /* 鍵を開ける */ } } printf ( "鍵は開いています。\n" ); return 0; }
NAZO ARE? KORE U-MU NAZO
C:\usr\c\> sample-001 鍵をかける 4 文字長さのパスワードを入力してください : NAZO 現在、鍵がかかっています 鍵を開けるためのパスワードを入力してください : ARE? パスワードが一致していません !!! 現在、鍵がかかっています 鍵を開けるためのパスワードを入力してください : KORE パスワードが一致していません !!! 現在、鍵がかかっています 鍵を開けるためのパスワードを入力してください : U-MU パスワードが一致していません !!! 現在、鍵がかかっています 鍵を開けるためのパスワードを入力してください : NAZO パスワードが一致しました 鍵は開いています。 C:\usr\c\>
Download : sample-002.c ( SJIS 版 )
/* * 文字列の配列への読み込み (scanf/gets は危険) */ #include <stdio.h> /* * main */ #define PASS_LEN 4 /* 鍵の長さ */ #define PASS_SIZE (PASS_LEN)+1 /* 鍵を納める配列のサイズ(長さ+1) */ #define ARY_SIZE 2 #define LOCK 1 /* 錠 */ #define KEY 0 /* 鍵 */ #define ever (;;) int main ( void ) { char str_ary[ARY_SIZE][PASS_SIZE]; int i; printf ( "鍵をかける 4 文字長さのパスワードを入力してください : " ); scanf ( "%s", str_ary[LOCK] ); /* 危険 !! */ for ever { /* 鍵が開くまで、ずっと周る */ printf ( "\n現在、鍵がかかっています\n" ); printf ( "鍵を開けるためのパスワードを入力してください : " ); scanf ( "%s", str_ary[KEY] ); /* 危険 !! */ for ( i = 0; i < PASS_LEN; i++ ) { /* パスワードチェック */ if ( str_ary[KEY][i] != str_ary[LOCK][i] ) { /* 違っている部分がある !! */ break; /* 後は調べる必要なし */ } } if ( i < PASS_LEN ) { /* 途中までしか調べてなければ、一致しなかった */ printf ( "パスワードが一致していません !!!\n" ); } else { /* そうでなければ、一致したので.. */ printf ( "パスワードが一致しました\n" ); break; /* 鍵を開ける */ } } printf ( "鍵は開いています。\n" ); return 0; }
LOCK AAAA DAME IYADAIYADA
C:\usr\c\> sample-002 鍵をかける 4 文字長さのパスワードを入力してください : LOCK 現在、鍵がかかっています 鍵を開けるためのパスワードを入力してください : AAAA パスワードが一致していません !!! 現在、鍵がかかっています 鍵を開けるためのパスワードを入力してください : DAME パスワードが一致していません !!! 現在、鍵がかかっています 鍵を開けるためのパスワードを入力してください : IYADAIYADA パスワードが一致しました 鍵は開いています。 C:\usr\c\>
Download : sample-003.c ( SJIS 版 )
/* * 文字列の配列への読み込み (scanf/gets は危険) */ #include <stdio.h> /* * main */ #define PASS_LEN 4 /* 鍵の長さ */ #define PASS_SIZE (PASS_LEN)+1 /* 鍵を納める配列のサイズ(長さ+1) */ #define ARY_SIZE 2 #define LOCK 1 /* 錠 */ #define KEY 0 /* 鍵 */ #define ever (;;) int main ( void ) { char str_ary[ARY_SIZE][PASS_SIZE]; int i; printf ( "鍵をかける 4 文字長さのパスワードを入力してください : " ); scanf ( "%4s", str_ary[LOCK] ); /* サイズを指定する */ for ever { /* 鍵が開くまで、ずっと周る */ printf ( "\n現在、鍵がかかっています\n" ); printf ( "鍵を開けるためのパスワードを入力してください : " ); scanf ( "%4s", str_ary[KEY] ); /* バッファオーバフローをさける安全な方法 */ for ( i = 0; i < PASS_LEN; i++ ) { /* パスワードチェック */ if ( str_ary[KEY][i] != str_ary[LOCK][i] ) { /* 違っている部分がある !! */ break; /* 後は調べる必要なし */ } } if ( i < PASS_LEN ) { /* 途中までしか調べてなければ、一致しなかった */ printf ( "パスワードが一致していません !!!\n" ); } else { /* そうでなければ、一致したので.. */ printf ( "パスワードが一致しました\n" ); break; /* 鍵を開ける */ } } printf ( "鍵は開いています。\n" ); return 0; }
LOCK AAAA DAME IYADAIYADA HELP LOCK
C:\usr\c\> sample-003 鍵をかける 4 文字長さのパスワードを入力してください : LOCK 現在、鍵がかかっています 鍵を開けるためのパスワードを入力してください : AAAA パスワードが一致していません !!! 現在、鍵がかかっています 鍵を開けるためのパスワードを入力してください : DAME パスワードが一致していません !!! 現在、鍵がかかっています 鍵を開けるためのパスワードを入力してください : IYADAIYADA パスワードが一致していません !!! 現在、鍵がかかっています 鍵を開けるためのパスワードを入力してください : パスワードが一致していません !!! 現在、鍵がかかっています 鍵を開けるためのパスワードを入力してください : パスワードが一致していません !!! 現在、鍵がかかっています 鍵を開けるためのパスワードを入力してください : HELP パスワードが一致していません !!! 現在、鍵がかかっています 鍵を開けるためのパスワードを入力してください : LOCK パスワードが一致しました 鍵は開いています。 C:\usr\c\>
Download : sample-004.c ( SJIS 版 )
/* * 文字列 "12345" を書式指定して表示 [ cf. Text p.213 List 9-4 ] */ #include <stdio.h> /* * main */ int main ( void ) { char str[] = "12345"; printf ( " 12345678 \n" ); printf ( "+--------+\n" ); printf ( "|%s|\n", str ); /* そのまま */ printf ( "|%3s|\n", str ); /* 最低 3 桁 (長ければ、指定なしと同じ) */ printf ( "|%.3s|\n", str ); /* 3 桁まで (それより長い部分は切捨て) */ printf ( "|%8s|\n", str ); /* 最低 8 桁 (短ければ、空白が補われ右寄せになる) */ printf ( "|%-8s|\n", str ); /* 最低 8 桁 (短ければ、空白が補われ左寄せになる) */ return 0; }
C:\usr\c\> sample-004 12345678 +--------+ |12345| |12345| |123| | 12345| |12345 | C:\usr\c\>
Download : sample-005.c ( SJIS 版 )
/* * 名前を尋ねて挨拶 (文字列の読込み) [ cf. Text p.213 List 9-4 ] */ #include <stdio.h> /* * main */ #define NAME_LENGTH 40 /* 日本語の場合は1文字が 2 byte になる事に注意 */ int main ( void ) { char name[NAME_LENGTH+1]; /* 名前を入れる文字配列 */ printf ( "御名前は : " ); scanf ( "%40s", name ); /* 必ず長さを指定する事 !! / 配列名の前には '&' は不要 */ printf ( "こんにちは、%sさん\n", name ); return 0; }
栗野俊一
C:\usr\c\> sample-005 御名前は : 栗野俊一 こんにちは、栗野俊一さん C:\usr\c\>
Download : sample-006.c ( SJIS 版 )
/* * 文字列の配列の初期化 ? [ cf. Text p.214 List 9-6 ] */ #include <stdio.h> /* * main */ #define STRING_SIZE 6 #define ArraySizeOf(Ary) (sizeof(Ary)/sizeof(Ary[0])) int main ( void ) { char str_ary[][STRING_SIZE] = { "Turbo", "NA", "DOHC" }; int i; for ( i = 0; i < ArraySizeOf(str_ary); i++ ) { printf ( "str_ary[%d] = \"%s\"\n", i, str_ary[i] ); } return 0; }
C:\usr\c\> sample-006 str_ary[0] = "Turbo" str_ary[1] = "NA" str_ary[2] = "DOHC" C:\usr\c\>
Download : sample-007.c ( SJIS 版 )
/* * 文字列の配列に複数の文字列を入力する [ cf. Text p.215 List 9-7 ] */ #include <stdio.h> /* * main */ #define STRING_LENGTH 127 #define STRING_SIZE (STRING_LENGTH+1) #define NUMBER_OF_STRINGS 3 int main ( void ) { char str_ary[NUMBER_OF_STRINGS][STRING_SIZE]; int i; for ( i = 0; i < NUMBER_OF_STRINGS; i++ ) { printf ( "str_ary[%d] : ", i ); scanf ( "%127s", str_ary[i] ); } for ( i = 0; i < NUMBER_OF_STRINGS; i++ ) { printf ( "str_ary[%d] = \"%s\"\n", i, str_ary[i] ); } return 0; }
S500L A8 SLK
C:\usr\c\> sample-007 str_ary[0] : S500L str_ary[1] : A8 str_ary[2] : SLK str_ary[0] = "S500L" str_ary[1] = "A8" str_ary[2] = "SLK" C:\usr\c\>
Download : sample-008.c ( SJIS 版 )
/* * 文字列の長さ [ cf. Text p.216 List 9-8 ] */ #include <stdio.h> /* */ #define EOS '\0' /* * str_length : 文字列の長さを求める */ unsigned int str_length ( const char str[] ) { unsigned int length; for ( length = 0; str[length] != EOS; length++ ) { /* 文字走査の基本パターン */ /* do nothing */ } return length; } /* * main */ #define STRING_LENGTH 127 #define STRING_SIZE (STRING_LENGTH+1) int main ( void ) { char str[STRING_SIZE]; int i; printf ( "文字列を入力してください : " ); scanf ( "%127s", str ); printf ( "文字列「%s」の長さは%uです。\n", str, str_length ( str ) ); return 0; }
SEC
C:\usr\c\> sample-008 文字列を入力してください : SEC 文字列「SEC」の長さは3です。 C:\usr\c\>
Download : sample-009.c ( SJIS 版 )
/* * 文字列の長さ [ 再帰版 ] */ #include <stdio.h> /* */ #define EOS '\0' /* * substr_length : 後文字列の長さを求める (再帰版) */ unsigned int substr_length ( const char str[], int pos ) { if ( str[pos] == EOS ) { /* 空文字列 */ return 0; /* 長さは 0 */ } else { return substr_length ( str, pos + 1 ) + 1; /* 更に後文字列の長さを求めて 1 ふやす */ } } /* * str_length : 文字列の長さを求める (後部分列を利用する) */ unsigned int str_length ( const char str[] ) { return substr_length ( str, 0 ); /* str 自身の長さは、後部分文字列 <str,0> の長さに等しい */ } /* * main */ #define STRING_LENGTH 127 #define STRING_SIZE (STRING_LENGTH+1) int main ( void ) { char str[STRING_SIZE]; int i; printf ( "文字列を入力してください : " ); scanf ( "%127s", str ); printf ( "文字列「%s」の長さは%uです。\n", str, str_length ( str ) ); return 0; }
SEC
C:\usr\c\> sample-009 文字列を入力してください : SEC 文字列「SEC」の長さは3です。 C:\usr\c\>
Download : sample-010.c ( SJIS 版 )
/* * 文字列の走査 [ cf. Text p.216 List 9-9 ] */ #include <stdio.h> /* */ #define EOS '\0' /* * put_string : 文字列を表示する(改行しない) */ void put_string ( const char str[] ) { unsigned int i; for ( i = 0; str[i] != EOS; i++ ) { putchar ( str[i] ); } } /* * main */ #define STRING_LENGTH 127 #define STRING_SIZE (STRING_LENGTH+1) int main ( void ) { char str[STRING_SIZE]; int i; printf ( "文字列を入力してください : " ); scanf ( "%127s", str ); put_string ( str ); putchar ( '\n' ); return 0; }
SEC
C:\usr\c\> sample-010 文字列を入力してください : SEC SEC C:\usr\c\>
Download : sample-011.c ( SJIS 版 )
/* * 文字列の走査 [ 再帰版 ] */ #include <stdio.h> /* */ #define EOS '\0' /* * put_substring : 後部分文字列を表示する */ void put_substring ( const char str[], int pos ) { if ( str[pos] != EOS ) { /* 空文字列でない */ putchar ( str[pos] ); /* 先頭の文字を出力し.. */ put_substring ( str, pos + 1 ); /* 残りは再帰で処理 */ } /* EOS なら空文字列 "" なので何もしなくてもよい */ } /* * put_string : 文字列を表示する(改行しない) */ void put_string ( const char str[] ) { put_substring ( str, 0 ); /* str の出力は <str,0> の出力 */ } /* * main */ #define STRING_LENGTH 127 #define STRING_SIZE (STRING_LENGTH+1) int main ( void ) { char str[STRING_SIZE]; int i; printf ( "文字列を入力してください : " ); scanf ( "%127s", str ); put_string ( str ); putchar ( '\n' ); return 0; }
SEC
C:\usr\c\> sample-011 文字列を入力してください : SEC SEC C:\usr\c\>
Download : sample-012.c ( SJIS 版 )
/* * 文字列内の数字を数える [ cf. Text p.219 List 9-10 ] */ #include <stdio.h> /* */ #define EOS '\0' /* * _str_dcount : 文字列内の数字の個数をそれぞれ求める */ void str_dcount ( const char str[] , int cnt[]) { unsigned int i; for ( i = 0; str[i] != EOS; i++ ) { if ( '0' <= str[i] && str[i] <= '9' ) { cnt[str[i]-'0']++; } } } /* * main */ #define STRING_LENGTH 127 #define STRING_SIZE (STRING_LENGTH+1) int main ( void ) { char str[STRING_SIZE]; int cnt[ '9' - '0' + 1 ] = {0}; /* '0' 〜 '9' で 10 文字 (植木算に注意) */ int digit; printf ( "文字列を入力してください : " ); scanf ( "%127s", str ); str_dcount ( str, cnt ); for ( digit = '0'; digit <= '9'; digit++ ) { printf ( "'%c' : %d\n", digit, cnt[ digit - '0'] ); } return 0; }
3.1415926532897265
C:\usr\c\> sample-012 文字列を入力してください : 3.1415926532897265 '0' : 0 '1' : 2 '2' : 3 '3' : 2 '4' : 1 '5' : 3 '6' : 2 '7' : 1 '8' : 1 '9' : 2 C:\usr\c\>
Download : sample-013.c ( SJIS 版 )
/* * 文字列内の数字を数える [ 再帰版 ] */ #include <stdio.h> /* */ #define EOS '\0' /* * _substr_dcount : 後部分文字列内の数字の個数をそれぞれ求める */ void substr_dcount ( const char str[] , int pos, int cnt[] ) { if ( str[pos] != EOS ) { cnt[str[pos]-'0']++; substr_dcount ( str, pos + 1, cnt ); } } /* * _str_dcount : 文字列内の数字の個数をそれぞれ求める */ void str_dcount ( const char str[] , int cnt[] ) { substr_dcount ( str, 0, cnt ); } /* * main */ #define STRING_LENGTH 127 #define STRING_SIZE (STRING_LENGTH+1) int main ( void ) { char str[STRING_SIZE]; int cnt[ '9' - '0' + 1 ] = {0}; /* '0' 〜 '9' で 10 文字 (植木算に注意) */ int digit; printf ( "文字列を入力してください : " ); scanf ( "%127s", str ); str_dcount ( str, cnt ); for ( digit = '0'; digit <= '9'; digit++ ) { printf ( "'%c' : %d\n", digit, cnt[ digit - '0'] ); } return 0; }
3.1415926532897265
C:\usr\c\> sample-013 文字列を入力してください : 3.1415926532897265 '0' : 0 '1' : 2 '2' : 3 '3' : 2 '4' : 1 '5' : 3 '6' : 2 '7' : 1 '8' : 1 '9' : 2 C:\usr\c\>
Download : sample-014.c ( SJIS 版 )
/* * 文字列をコピーする [ 再帰版 ] */ #include <stdio.h> /* */ #define EOS '\0' /* * _substr_copy : 後部分列コピー ( dst には十分な.. ) */ void substr_copy ( const char src[] , int spos, char dst[], int dpos ) { if ( src[spos] == EOS ) { /* 空文字列ならば、空文字列をコピー */ dst[dpos] = EOS; } else { /* そうでないなら */ dst[dpos] = src[spos]; /* 先頭をコピーし.. */ substr_copy ( src, spos + 1, dst, dpos + 1 ); /* 後は再帰で処理. */ } } /* * _str_copy : 文字列をコピー ( dst には src の内容がコピーできる十分な領域が必要 ) */ void str_copy ( const char src[] , char dst[] ) { substr_copy ( src, 0, dst, 0 ); /* 全体をコピーするには、後部分文字列をコピー */ } /* * main */ #define STRING_LENGTH 127 #define STRING_SIZE (STRING_LENGTH+1) int main ( void ) { char src[STRING_SIZE]; char dst[STRING_SIZE] = ""; printf ( "文字列を入力してください : " ); scanf ( "%127s", src ); printf ( "入力 : src = %s\n", src ); printf ( "事前 : dst = %s\n", dst ); str_copy ( src, dst ); /* 文字列のコピー */ printf ( "事後 : dst = %s\n", dst ); return 0; }
123abc789
C:\usr\c\> sample-014 文字列を入力してください : 123abc789 入力 : src = 123abc789 事前 : dst = 事後 : dst = 123abc789 C:\usr\c\>
Download : sample-015.c ( SJIS 版 )
/* * 文字列の配列の表示 (関数版) [p.220, List 9-12] */ #include <stdio.h> #define STRING_SIZE 6 /* * put_sarray : 文字列の配列の表示 */ void put_sarray ( char str_ary[][STRING_SIZE], int size ) { int i; for ( i = 0; i < size; i++ ) { printf ( "str_ary[%d] = \"%s\"\n", i, str_ary[i] ); } } /* * main */ #define ArraySizeOf(Ary) (sizeof(Ary)/sizeof(Ary[0])) int main ( void ) { char str_ary[][STRING_SIZE] = { "Turbo", "NA", "DOHC" }; int i; put_sarray ( str_ary, ArraySizeOf(str_ary) ); return 0; }
C:\usr\c\> sample-015 str_ary[0] = "Turbo" str_ary[1] = "NA" str_ary[2] = "DOHC" C:\usr\c\>
Download : sample-016.c ( SJIS 版 )
/* * 大文字小文字の変換 [p.222, List 9-13] */ #include <stdio.h> #include <ctype.h> /* */ #define EOS '\0' /* * str_toupper : 文字列内の小文字を大文字に変換する */ void str_toupper ( char str[] ) { unsigned int i; for ( i = 0; str[i] != EOS; i++ ) { str[i] = toupper ( str[i] ); } } /* * str_tolower : 文字列内の大文字を小文字に変換する */ void str_tolower ( char str[] ) { unsigned int i; for ( i = 0; str[i] != EOS; i++ ) { str[i] = tolower ( str[i] ); } } /* * main */ #define STRING_LENGTH 100 #define STRING_SIZE (STRING_LENGTH+1) int main ( void ) { char str [ STRING_SIZE ]; printf ( "文字列を入力してください : " ); scanf ( "%100s", str ); str_toupper ( str ); printf ( "大文字 : %s\n", str ); str_tolower ( str ); printf ( "小文字 : %s\n", str ); return 0; }
BohYoh
C:\usr\c\> sample-016 文字列を入力してください : BohYoh 大文字 : BOHYOH 小文字 : bohyoh C:\usr\c\>
Download : sample-017.c ( SJIS 版 )
/* * 大文字小文字の変換 [再帰版] */ #include <stdio.h> #include <ctype.h> /* */ #define EOS '\0' /* * substr_toupper : 部分文字列内の小文字を大文字に変換する */ void substr_toupper ( char str[], int pos ) { if ( str[pos] != EOS ) { str[pos] = toupper ( str[pos] ); substr_toupper ( str, pos + 1 ); } } /* * str_toupper : 文字列内の小文字を大文字に変換する */ void str_toupper ( char str[] ) { substr_toupper ( str, 0 ); } /* * substr_tolower : 後部分文字列内の大文字を小文字に変換する */ void substr_tolower ( char str[], int pos ) { if ( str[pos] != EOS ) { str[pos] = tolower ( str[pos] ); substr_tolower ( str, pos + 1 ); } } /* * str_tolower : 文字列内の大文字を小文字に変換する */ void str_tolower ( char str[] ) { substr_tolower ( str, 0 ); } /* * main */ #define STRING_LENGTH 100 #define STRING_SIZE (STRING_LENGTH+1) int main ( void ) { char str [ STRING_SIZE ]; printf ( "文字列を入力してください : " ); scanf ( "%100s", str ); str_toupper ( str ); printf ( "大文字 : %s\n", str ); str_tolower ( str ); printf ( "小文字 : %s\n", str ); return 0; }
BohYoh
C:\usr\c\> sample-017 文字列を入力してください : BohYoh 大文字 : BOHYOH 小文字 : bohyoh C:\usr\c\>