Presentation is loading. Please wait.

Presentation is loading. Please wait.

第13章 文字の取り扱い方 13.1 文字と文字型変数 13.2 文字列 13.3 文字型配列への文字列の代入

Similar presentations


Presentation on theme: "第13章 文字の取り扱い方 13.1 文字と文字型変数 13.2 文字列 13.3 文字型配列への文字列の代入"— Presentation transcript:

1 第13章 文字の取り扱い方 13.1 文字と文字型変数 13.2 文字列 13.3 文字型配列への文字列の代入
13.4 キーボードからの文字列の入力 13.5 文字型配列と関数

2 13.1 文字と文字型変数 これまでに扱ったのは数値型変数 プログラミングでは文字も扱う場合が多い 整数型
13.1 文字と文字型変数 これまでに扱ったのは数値型変数 整数型   int : 〜   浮動小数点型  float : 〜 1038  double : 〜 10308 プログラミングでは文字も扱う場合が多い 文字型 char を用いる 他に、short int, long int, long double, また、unsigned がつくものなどがある。 詳細はプログラミング演習Ⅰの資料を参照

3 文字型変数に文字を代入 プログラム例 13.1.1 より抜粋 1文字 = 1バイトの数値 int main(void) {
char x; x = 'H'; printf("%c¥n", x); return 0; } 文字型変数 x を宣言 代入文でOK 1文字はシングル クォート(')でくくる 1文字用の書式指定子 p.180, 表A.3 ASCIIコード 1文字 = 1バイトの数値 8ビット(0~255)

4 文字型変数に文字を代入 プログラム例 13.1.1 の改変 #include <stdio.h> int main(void)
{ char x, y, z, u, v, w; x = 'H'; y = 'a'; z = 'p'; u = 'p'; v = 'y'; w = '!'; printf("%c%c%c%c%c%c¥n", x, y, z, u, v, w); printf("%d %d %d %d %d %d¥n", x, y, z, u, v, w); printf("%x %x %x %x %x %x¥n", x, y, z, u, v, w); return 0; } character decimal %c 文字 %d 10進数 %x 16進数 hexadecimal

5 文字列 William Shakespeare を配列変数 x に代入
13.2 文字列 複数個の文字(文字列、string)は「char 型の配列」として扱う。 文字列はダブルクォート(")でくくること。 文字列の最終文字の次に、文字列の最後を示す \0 が入る。 null文字 プログラム例 より抜粋 文字列 William Shakespeare を配列変数 x に代入 int main(void) { char x[20] = {"William Shakespeare"}; printf("%s¥n", &x[0]); return 0; } 19字だが、 20字分用意 ここで、配列変数 x の先頭番地を指定すると、 x のすべてを表示する。 ただし最後の ¥O は表示しない 文字列用の書式指定子

6 文字列は配列に格納される W int main(void) i 1000 x[0] { l 1001 char x[]= 1002
{"William Shakespeare"};  printf("%s¥n", x); return 0; } 1000 1001 1002 x[0] x[1] x[2] x[3] x[4] &x[0] は単に x でよい e \0 x[18] 文字列の終わり x[19] 正体は1バイトの数字の0

7 13.2 文字列 プログラム例 13.2.2 の改変 配列の長さ < 文字列の長さ の場合にどうなるか、試してみよう
13.2 文字列 配列の長さ < 文字列の長さ の場合にどうなるか、試してみよう プログラム例 の改変 #include <stdio.h> int main(void) { char x[??] = {"William Shakespeare"}; printf("%s¥n", x); return 0; } ここの値を変えて、配列の 長さを1つずつ減らしてみよ

8 文字列の正体 プログラム例 13.2.2 の改変 #include <stdio.h> int main(void) {
int i; char x[20] = {"William Shakespeare"}; printf("%s¥n", x); for (i = 0; i < 20; i++) printf(" %d", x[i]); printf("\n"); return 0; } この出力結果を p.180、表A.3 のASCIIコード と比べてみよう

9 13.2 文字列 プログラム例 13.2.4 複数の文字列を扱う場合 → 2次元配列を使う #include <stdio.h>
13.2 文字列 複数の文字列を扱う場合 → 2次元配列を使う プログラム例 #include <stdio.h> int main(void) { char name[3][20] = {"William Shakespeare", "William Clinton", "William Henry"}; int i; for (i = 0; i < 3; i++) printf("%s¥n", name[i]); printf("\n"); return 0; } 前の数字が文字列の数 後の数字は「文字数+1」以上に

10 13.3 文字列の代入 配列(文字列)に代入文は使えない 文字列処理関数 (string.h を include)
13.3 文字列の代入 配列(文字列)に代入文は使えない 文字列処理関数 (string.h を include) strcpy(char *dst, char *src) string copy (ストリング・コピー)の略 引数の順序は代入文 dst ← src に対応 引数はポインタ(文字型配列の名前)

11 a ← "William Shakespeare"
13.3 文字列の代入 プログラム例 #include <stdio.h> #include <string.h> int main(void) { char a[31], b[31]; strcpy(a, "William Shakespeare"); printf("%s\n", a); strcpy(b, a); printf("%s¥n", b); return 0; } 入れ物は2つ用意 a ← "William Shakespeare" b ← a 文字列の代入 a William Shakespeare 実際にコピー b William Shakespeare

12 a ← "William Shakespeare"
13.3 文字列の代入(もどき) プログラム例 の改変 #include <stdio.h> int main(void) { char a[] = "William Shakespeare", *b; printf("%s\n", a); b = a; printf("%s¥n", b); return 0; } 入れ物は1つ a ← "William Shakespeare" 文字型ポインタを用意 b ← a アドレスデータの代入 データは共用 a William Shakespeare b

13 13.4 キーボードからの文字列の入力 プログラム例 13.4.2 #include <stdio.h>
13.4 キーボードからの文字列の入力 プログラム例 101 は文章を読み込むのに 十分と考えられる適当な数。 特別な意味はない #include <stdio.h> int main(void) { char sentence[101]; printf("文章を入力して下さい"); gets(sentence); puts(sentence); return 0; } キーボードから文字列を受け取り、 の配列変数 sentence に代入する ディスプレイに表示 gets は get string、puts は put string と覚えれば良い ゲットエス プットエス 参考: C言語の読み方サイト

14 失敗例 プログラム例 13.4.1 と 13.4.2 の混合 #include <stdio.h> int main(void)
{ char surname[51], sentence[101]; printf("姓を入力してください :"); scanf("%s", surname); printf("姓は %s です.\n", surname); printf("文章を入力してください "); gets(sentence); puts(sentence); return 0; } gets, getc, getchar があるときは scanf は使わない 製品開発には挙動不審な scanf は使われない

15 解決例 プログラム例 13.4.1 と 13.4.2 の混合 #include <stdio.h> int main(void)
{ char s[101], surname[51], sentence[101]; printf("姓を入力してください :"); gets(s); sscanf(s, "%s", surname); printf("姓は %s です.\n", surname); printf("文章を入力してください "); gets(sentence); puts(sentence); return 0; } gets + sscanf なら OK

16 13.5 文字型配列と関数 関数に文字列を渡す → ポインタ変数(配列名)を引数に プログラム例 13.5.2 2次元配列のまま渡す場合
13.5 文字型配列と関数 関数に文字列を渡す → ポインタ変数(配列名)を引数に プログラム例 2次元配列のまま渡す場合 #include <stdio.h> #define NSIZE 40 #define N_Mem 3 void input_name(int n, char name[][NSIZE]); void print_name(int n, char name[][NSIZE]); int main(void) { char f_and_g[N_Mem][NSIZE]; input_name(N_Mem, f_and_g); print_name(N_Mem, f_and_g); return 0; } 1行あたり40文字で3行分 の2次元配列を宣言 ポインタ(その配列 の先頭番地を指す) を引数とする 文字列を 読込む関数 文字列を 表示する関数

17 13.5 文字型配列と関数 プログラム例 (つづき) void input_name(int n, char name[][NSIZE]) { int i; for (i = 0; i < n; i++) { printf("苗字と名前を入力してください :"); gets(name[i]); } void print_name(int n, char name[][NSIZE]) for (i = 0; i < n; i++) printf("あなたの苗字と名前は %s です.\n", name[i]);

18 13.5 文字型配列と関数 プログラム例 13.5.3 ポインタ配列として渡す場合 #include <stdio.h>
13.5 文字型配列と関数 プログラム例 ポインタ配列として渡す場合 #include <stdio.h> #define NSIZE 40 #define N_Mem 3 void input_name(int n, char *name[]); void print_name(int n, char *name[]); int main(void) { int i; char f_and_g[N_Mem][NSIZE], *name[N_Mem]; for (i = 0; i < N_Mem; i++) name[i] = f_and_g[i]; input_name(N_Mem, name); print_name(N_Mem, name); return 0; } NSIZEが不要に 文字型ポインタ配列を用意 行ごとに2次元配列を 文字型ポインタ配列にすり替え

19 13.5 文字型配列と関数 プログラム例 13.5.3 (つづき) void input_name(int n, char *name[])
13.5 文字型配列と関数 プログラム例 (つづき) void input_name(int n, char *name[]) { int i; for (i = 0; i < n; i++) { printf("苗字と名前を入力してください :"); gets(name[i]); } void print_name(int n, char *name[]) for (i = 0; i < n; i++) printf("あなたの苗字と名前は %s です.\n", name[i]); NSIZEが不要に

20 スキルアップタイム 1 以下の動作をするプログラムを作成せよ。 ディスプレイに「文章を入力して下さい」と表示
キーボードから入力された適当な英語の文章   (例えば Boys be ambitious! など)を読み取る その文章をディスプレイに表示 これを3回繰り返す   (1、2、3回目は各々違う文章を入力してみる) プログラム例 を参照

21 スキルアップタイム 1 のプログラムの流れ printf で“文章を入力して下さい” main i = 1...3
スキルアップタイム 1 のプログラムの流れ ヘッダファイル、関数、記号定数の宣言 3つの文章を記憶せず、読み込んで表示するだけなら、1つの文章用1次元配列で OK 変数宣言(必要な変数と そのデータ構造を決める) printf で“文章を入力して下さい” main i = 1...3 gets で文章を読み取り、変数に入れる puts で文章を表示 文字型配列sentence[] 終了

22 スキルアップタイム 2 作成したプログラムを以下のように変更せよ 最初にディスプレイに「3つの文章を入力して下さい」と表示
ディスプレイに「文章 i:」(i = 1,2,3)と表示し、キーボードから入力される英語の文章を読み取る。これを3回繰り返す(この時点では表示はしない) 3個の文章をまとめてディスプレイに表示 3個の文章を記憶する必要有り  → 文字型の2次元配列が必要

23 スキルアップタイム 2 のプログラムの流れ (その1)
スキルアップタイム 2 のプログラムの流れ (その1) ヘッダファイル、関数、記号定数の宣言  変数宣言(必要な変数と そのデータ構造を決める) main で全ての作業を行うタイプ (この程度の課題ならこれでも十分) printf で“文章を入力して下さい” main i = 1...3 gets で文章を読み取り、配列変数に入れる i = 1...3 puts or printf で配列変数に入った文章を表示 終 了

24 スキルアップタイム 2 の プログラムの流れ (その2)
プログラム例 を参照 関数名、変数名は 自分の好きなように決める ヘッダファイル、関数などの宣言 文章を読み取る関数 input_sentence 変数宣言(必要な変数と そのデータ構造を決める) これは一例 printf で “文章を入力して下さい” main 文章を読み取る関数 i = 1...3 文章を表示する関数 gets で文章を読み取る 終 了 文字列配列(ポインタ)を引数としてデータをやりとりする 文章を表示する関数 print_sentence i = 1...3 printf or puts で文章を表示

25 スキルアップタイム3 すべてできた人は、演習問題の問題13.3、問題13.5 をやってみよう。
問題13.3 用のデータを考えるのが面倒な人は以下のデータを使ってください。 学籍番号 氏  名 科目Aの得点 1001 Akanishi Hideo 55 1005 Ishihara Satoshi 64 1013 Kitano Keiko 71 1024 Sakaguchi Erika 85 1030 Tanaka Kazuya 68

26 本日のパズル 次のプログラムは何を出力するか
#define PRINT(x) printf(#x"=%d\n",(x)) int i=0; main() { auto int i=1; PRINT(i); int i=2; i += 1; } 1 2 3 4 5


Download ppt "第13章 文字の取り扱い方 13.1 文字と文字型変数 13.2 文字列 13.3 文字型配列への文字列の代入"

Similar presentations


Ads by Google