Comments
Description
Transcript
スライド
Cプログラミング講座 CCCCCCCCCCCCC CCC::::::::::::C CC:::::::::::::::C C:::::CCCCCCCC::::C C:::::C CCCCCC C:::::C C:::::C C:::::C C:::::C C:::::C C:::::C C:::::C CCCCCC C:::::CCCCCCCC::::C CC:::::::::::::::C CCC::::::::::::C CCCCCCCCCCCC 第7回 2014/6/26 情報工学研究部 1 文字 文字はコンピュータでは数値として扱われる。 その文字に数値を割り当てたものを文字コードという。 (また、文字と数値表現の対応を指すこともある。) C言語において、文字定数は'x'のようにシングルクォー トの中に1文字を書く。 例えば、ASCII文字コードにおいては、'0'は値48(0x30) で表現され、数値としての0とは関係がない。 ※ 以降、断りが無い限りASCII文字コードとする 情報工学研究部 2 ASCII文字コード 情報工学研究部 E-Words: http://e-words.jp/p/r-ascii.html より引用 3 char型 C言語では、1文字を格納するためにchar型(1 バイト)を用いる。 #include <stdio.h> int main(void) { char c = 'a'; printf("文字: %c¥n", c); printf("数値: %d (0x%2x)¥n", c, c); return 0; } 情報工学研究部 [実行結果] 文字: a 数値: 97 (0x61) 4 getchar() / putchar() getchar()は標準入力から1文字読み込む。 読み込み失敗または終端に達した場合、EOFを返す。 putchar()は標準出力に1文字出力する。 それぞれ返り値、引数はint型であることに注意。 #include <stdio.h> int main(void) { int c; while((c = getchar()) != EOF){ puthar(c); } return 0; } 情報工学研究部 [実行結果] Programming⏎ Programming [Ctrl+D] UNIXではCtrl+D、Windowsでは Ctrl+Zで入力を終了。 5 文字列 C言語では文字列型は存在せず、文字列はchar型の 配列で表される。文字列の終端には、終端を意味する ヌル文字'¥0'が必要である。 即ち、n文字の文字列を表すにはn+1の大きさの配列を 必要とする。 また、ダブルクォートで囲まれた文字列を文字列リテラ ルといい、その文字列を表す配列となる。 ☆特に文字列の取り扱いは、誤りを犯しやすいので正しい理解 と記述が求められる。 情報工学研究部 6 文字列の例 #include <stdio.h> int main(void) { char s1[6] = {'a', 'b', 'c', 'd', 'e', '¥0'}; char s2[6] = "abcde"; // 配列の大きさに注意 char s3[] = "abcde"; char *s4 = "abcde"; printf("%s¥n", printf("%s¥n", printf("%s¥n", printf("%s¥n", s1); s2); s3); s4); [実行結果] abcde abcde abcde abcde return 0; } 情報工学研究部 7 文字列 前ページの例で、s1,s2,s3,s4の出力は全て等しいこ とが分かる。 s1,s2,s3は同等な文字列の配列である。 s2,s3は文字列リテラルによる配列の初期化と言える。 s4は文字列リテラルに対するポインタである。 s4のように文字列リテラルをポインタで指した場合、 注意すべき点がある。 それは、規格上、文字列リテラルの変更は未定義とさ れていることである。(処理系依存) 情報工学研究部 8 文字列リテラルの変更 #include <stdio.h> int main(void) { char s1[] = "abcde"; char *s2 = "abcde"; 文字列リテラルの参照は、以下のように const修飾すべきなのである。 const char *s3 = "abcde"; s1[0] = 'A'; s2[0] = 'A'; // 文字列リテラルの変更 printf("%s¥n", s1); printf("%s¥n", s2); return 0; } 情報工学研究部 9 gets() / fgets() char *gets(char *s) 標準入力から改行文字'¥n'またはEOFまで文字列を読み取 り、sの指す配列に格納する。改行文字は'¥0'に置き換えら れる。読み取り失敗時にはNULLポインタが返される。 char *fgets(char *s, int n, FILE *fp) fpが指すストリームから、n-1バイト目まで、あるいは改 行文字'¥n'またはEOFまで文字列を読み取り、末尾に '¥0'を付加し、sの指す配列に格納する。 なお、改行文字も含まれて格納される。 fpにstdinを指定することで、標準入力から入力できる。 情報工学研究部 10 例 #include <stdio.h> int main(void) { char str[20]; if(gets(str) != NULL){ printf("出力: %s¥n", str); } [実行結果] Programming⏎ 出力: Programming Debugging⏎ 出力: Debugging ⏎ if(fgets(str, 20, stdin) != NULL){ printf("出力: %s¥n", str); } return 0; } 情報工学研究部 11 [発展] gets()の問題 前ページの例では、gets()、fgets()のどちらを用い ても、同じように入力ができているように見える。 しかし、現在では一般的に※gets()の使用は避けるべ きとされている。 いくつかの入力を試してみてほしい。 入力された文字列の長さが、19文字より大きい場合 の動作がどうなるのか、考えてみること。 ※最新のC言語規格C11(ISO/IEC 9899:2011)で、gets関数は廃止されている。 情報工学研究部 12