文字列

アルファベットや数字など,半角文字列の扱い方

文法

例)

例2)c のほうには \0 を入れていない.そのため,実行結果がおかしくなる.

実行結果例(環境に依存して実行結果が変わる可能性があります)

※ printf は,メモリ上の文字を順番に見ていき,\0 が出てくるまで出力する.上の例だと,メモリ上に c と d の内容が並んで割り当てられているため,c の内容を出力した後,dの内容が出力されたと考えられる.

全角文字列の扱い方

例)sizeof という演算子を使って,文字列にいくつの char 変数が使われているかを確認してみる.

【sizeof】

Mac など,UTF-8 を文字コードとする環境では,以下のように表示される.16 は (3バイト) x (5文字) + (文字列の最後 \0 に1バイト).40 のほうも (3バイト) x (13文字) + (文字列の最後 \0 に1バイト)

特殊な文字

次の2つは,まれに使うことがあるので,特殊な扱い方をする文字として覚えておくと良い.

例題)以下のソースコードが記述されているファイルを./main.c とし,対応する実行ファイルを ./main とする.これを ./main < ./main.c として実行したときに表示される内容を説明せよ.

文字列を扱う関数の例

注意:配列の長さを間違えるとメモリの書き込んではいけない領域にデータを書き込んでしまう可能性があるので,十分,注意すること.

【コラム】 最近の gcc では,コンパイルするときに -g -fsanitize=address をつけておくと,書き込んではいけない領域に書き込んでいないかどうか,ある程度,チェックしてくれる.

上のプログラムを普通にコンパイル

すると,特に問題なくコンパイルされ,実行出来るが,例えば gitpod 上で実行してみると

など,d の表示がおかしくなってしまった.このプログラムは,配列 c に,c が保存できる量よりも多いデータを書き込んでいるので,本来は実行できてはいけないプログラムであり,そのため,このように予測不能な動作をする可能性がある.これを防ぐには

としてコンパイルすると良い.コンパイルは出来るものの,実行すると

などのようにエラーが発生し,実行できなくなっている.もしも,配列の添え字の範囲間違いなどが原因でプログラムが妙な動作をしている場合, -g -fsanitize=address をつけておくと,ミスに気づけるかもしれない.

 

文字列のコピー(strcpy)

文字列は配列として扱うが,配列を素直にコピーしようとしても,コンパイルできず,エラーとなる.例えば,下のプログラムはコンパイルできない.

文字列のコピーには strcpy を使う.

実行結果)

 

文字列の連結(strcat)

実行結果)

 

文字列を変換(atoi, atof)

実行結果例)

実行結果例)

宿題: 文字列の長さを求める関数を作りたい(ただし,長さを求めるときに,文字列の最後を表す \0 は除くものとする.)そうなるように,次のプログラムを修正せよ.