プログラミング演習Ⅱ 第9回 文字列 情報・知能工学系 山本一公 [email protected] 前回の課題の解説・ポイント(1) • 課題7-1 #define swap(type, x, y) {type tmp = x; x = y; y = tmp;} – “{” “}” で囲むことによって、ブロックを作る。それ によって、変数 tmp のスコープをブロック内に閉じ 込める。 – gcc の ”-E” オプションで、マクロの展開を実際に確 かめることができる。 – 第3の変数を使わずに、変数の値を交換することは可 能である(そういう方法がある)。その場合、typeは 不要。 前回の課題の解説・ポイント(2) • 課題7-2 int main(void) { int ch, count = 0; while ((ch = getchar()) != EOF) { if (ch == ’\n’) count++; } printf(”行数 = %d\n”, count); } – 上記は改行を数えるだけの基本形 – 行の途中で EOF が来た場合にどうするか?を考える と 少し複雑になる 今日の内容 • 教科書 pp.207~223 • 文字列の基本 • 文字列リテラル – ナル文字 • 文字列・文字配列 • 文字列の配列 • 文字列の操作 文字列(1) • 文字列リテラル(文字列定数) – ダブルクォートで文字を囲んだもの – 「”ABC”」 • 文字列 – C言語には「文字列型」が存在しないので、 文字列の実体は「文字型(char型)の配列」 – 文字列の終端に ’\0’(数字のゼロ。ナル文 字)が入っている A B C \0 文字列(2) • 文字列は printf() では ”%s” で表示できる – 最初のナル文字までが表示される – ナル文字が見つからなかったら、配列を定義 した範囲を越えて延々と表示され続ける • 文字列操作でよくやるミスなので、注意すること • 初期化 – 宣言時に代入して初期化できる char ss[] = {‘A’, ‘B’, ‘C’, ‘\0’}; // 配列の初期化と同じ char ss[] = “ABC” // 面倒なので普通はこちら 文字列(3) • 代入 – 初期化は文字列リテラルでできる – 文字列リテラルを代入することはできない str = {‘A’, ‘B’, ‘C’, ‘\0’}; str = “ABC” // どちらもできない! – 代入は1文字ずつ str[0] = ‘A’; str[1] = ‘B’; str[2] = ‘C’; str[3] = ‘\0’; • すなわち「配列と同じ」です 文字列(4) • 空文字列 – 内容が空の文字列=先頭がナル文字 • scanf() による文字列の読み込み char name[40]; // 何文字入れられるか分からないので多めに scanf(“%s”, name); 文字列の 場合は %s 先頭に”&”は いらない scanfの危険性 • scanf() で ”%s” 指定子を用いると、何文字でも入 力できてしまう! ⇒ 用意した文字配列の要素を越えてしまう場合 がある ⇒ 「バッファーオーバーラン」 – システムプログラムで起きると、セキュリティホー ルになる場合がある – “%10s” のように入力できる文字数を制限することで 回避できる – gets() にも同じ問題。gets() の場合は回避策がない。 • gets() は使わない!代わりに fgets()を使う。 文字列の配列 • 文字列は文字型の配列 • 2次元配列にすれば、文字列の配列になる char cs[][6] = {“Turbo”, “NA”, “DOHC”}; 要素文字列の最大長+1以上必要 – 文字列リテラルが使える点を除けば、 2次元配列の初期化と同じ – cs[0][0]が’T’、cs[1][0]が’N’、cs[2][0]が’D’、 cs[0][1]が’u’、cs[1][1]が’A’、cs[2][1]が’O’ 文字列の操作(1) • 文字列の長さを数える – p.216, List 9-8 – ナル文字が来るまでwhileを回して 文字数を増やしていく • 1文字ずつ扱う – p.218, List 9-9 – ナル文字が来るまでwhileを回して putchar() で1文字ずつ表示する • 普通の配列と同じ 文字列の操作(2) • 文字列の配列の受け渡し – 2次元配列の場合と同じ • p.221, Column 9-1「文字列の初期化」 – これもよくやるミス – 「ナル文字がない」⇒ printf() で ”%s” で表示 したときに、文字列の終端がないので、訳の 分からない表示になってしまう可能性が高い 文字列の操作(3) • 大文字・小文字の変換 – toupper() / tolower() – 引数は int 型であることに注意 • p.260, 11-3節 – 「文字列を扱うライブラリ関数」 – 文字列の長さを数えたり、文字列をコピーす る関数が標準で用意されている – 普通はこれらを使う 今週の課題 1. p.219、演習9-8のプログラムを作成せよ。main関数等も 作成して、完成したプログラムを作成すること。 2. 2つの文字列 str1[], str2[] が、英字については大文字・ 小文字を区別しないで、一致しているかどうか判定す る関数 int stricomp(const char str1[], const char str2[]) を作 成せよ。返却値は一致していれば1、不一致なら0とす ること。 また、その関数を利用して2つのテキストファイルの 内容が大文字・小文字を区別しないで一致しているか どうか判定するプログラムを作成せよ。ファイル名は キーボードから入力できるようにすること。 課題8-2後半の考え方 1. scanf()でファイル名を2つ入力 2. 両方のファイルから1行ずつ読み込む – 改行が来るまでfgetc()で1文字ずつ読んで文字列と して保存 • – fgets()を使って行単位で読む方が簡単 1行の長さを適当に(長めに)決めておく 3. 作成した関数を使って比較 – 一致しない箇所が見つかった時点で、一致しないと 表示して終了 4. 2.以下を繰り返す。ファイルの最後まで一致し ない箇所がなければ一致と見做す。 レポートについて • 電子メールで提出 – 提出先は [email protected] – Subjectを「プログラミング演習2 課題8提出 番号・氏名 」とすること – C言語ソースファイルを添付する 学籍 • メールの本文には何も書かなくて良いです – ソースファイルの頭にコメントで以下の情報を入れる • 学籍番号・氏名 • プログラムの説明(どのように動くのか、工夫した点等) • 実行結果(長い場合は一部)を貼る – 提出締切は、1月9日(水) 12:00 (次の授業の前) 授業用Webサイト • URL: http://www.slp.cs.tut.ac.jp/~kyama/programming2/ – 課題のpdfファイルが置いてあります。 – 授業で使ったpptファイルを置いていきます。 • 質問メールは、以下のどちらかのアドレスまで – [email protected] – [email protected] • C-515へ直接質問しに来ても構いません
© Copyright 2024 ExpyDoc