
C言語入門|文字列を加工・生成する関数
ここからはいよいよ、
文字列を実際に書き換えたり、新しく作ったりする関数
を扱っていきます。
strlen や strcmp は「読むだけ」の関数でしたが、
今回登場する関数は メモリに書き込む という点で一段レベルが上がります。
便利になる反面、
使い方を間違えるとオーバーランに直結する
関数たちでもあります。
だからこそ、ここで大切なのは
「この関数は、どの領域に、どこまで書き込むのか」
を常にイメージすることです。

文字列を加工する関数の共通ルール
今回登場する関数には、共通した前提があります。
| 共通ルール | 内容 |
|---|---|
| 先頭アドレス渡し | 文字列は必ず先頭アドレスで受け渡す。 |
| \0 前提 | \0 に到達するまでを文字列として扱う。 |
| 容量チェックはしない | 十分な領域があるかは呼び出し側の責任 |
特に最後の
容量チェックを自動では行わない
という点が重要です。
これらの関数は、
「あると信じて、あるだけ書く」
という、非常に正直な動作をします。
strcpy ― 文字列をまるごとコピーする
ある文字列を、別のメモリ領域にそのままコピーしたい。
そんなときに使うのが strcpy 関数です。
strcpy の書式
char* strcpy(char* dest, const char* src);| 引数 | 意味 |
|---|---|
| dest | コピー先の先頭アドレス(十分な領域が必要) |
| src | コピー元文字列の先頭アドレス |
| 戻り値 | dest と同じアドレス |
strcpy は、
- src の先頭から
- \0 に到達するまで
1文字ずつ dest にコピーします。
重要な注意点
strcpy は、
dest の大きさを一切確認しません。
そのため、
- src が長すぎる
- dest の確保サイズが足りない
このどちらかが起きると、
即オーバーランです。
strcpy の動作を領域で考える
strcpy を安全に使うためには、
「3つの領域」の考え方がそのまま役立ちます。
| 領域 | 意味 |
|---|---|
| 使用中 | コピーされる文字列部分 |
| 使用可能 | コピーしてよい領域 |
| 使用禁止 | 触れてはいけない領域 |
dest の使用可能領域が、
src の文字列長 + 1(\0 分)
より小さい場合は、使ってはいけません。
strcat ― 文字列を後ろに連結する
既存の文字列の後ろに、
別の文字列をつなげたいときに使うのが strcat です。
strcat の書式
char* strcat(char* dest, const char* src);| 引数 | 意味 |
|---|---|
| dest | 連結後の文字列が格納される先頭アドレス |
| src | 後ろに追加する文字列の先頭アドレス |
| 戻り値 | dest と同じアドレス |
strcat は、
- dest の \0 を探す
- その位置から src をコピー
- 最後に \0 を付け直す
という動作をします。
strcat は特に危険になりやすい
strcat は、
見た目以上に危険度が高い関数です。
なぜなら、
- 現在の文字列長
- これから追加する文字列長
- 使用可能領域の残り
この3つをすべて把握していないと、
簡単にオーバーランしてしまうからです。
よくある落とし穴
char str[] = "hello";
strcat(str, "world"); // 危険この場合、str は
必要最低限の6バイトしか確保されていません。
後ろに連結できる余裕はゼロです。
sprintf ― 文字列を「生成」する関数
sprintf は、
printf の仲間でありながら、
画面には何も表示しません。
代わりに、
指定したメモリ領域に文字列を書き込みます。
sprintf の書式
int sprintf(char* dest, const char* format, ...);| 引数 | 意味 |
|---|---|
| dest | 書き込み先の先頭アドレス |
| format | printf と同じ書式文字列 |
| ... | 書式に対応する値 |
| 戻り値 | 書き込んだ文字数(\0 は含まない) |
sprintf を使うと、
- 数値と文字列を組み合わせる
- 整形されたメッセージを作る
といった処理が、とても簡単になります。
sprintf も容量チェックはしない
sprintf も例外ではありません。
- 書き込む文字数
- dest の確保サイズ
この関係を考えずに使うと、
strcpy や strcat と同じくオーバーランします。
「printf の感覚で使うと危険」
という点は、必ず覚えておきましょう。
文字列加工関数を使うときの心得
最後に、この節の要点をまとめます。
| 心得 | 内容 |
|---|---|
| 書き込み先の容量を把握する | 常に何バイトあるかを意識 |
| \0 の存在を忘れない | +1 バイトは必須 |
| 3つの領域を思い出す | 使用中・使用可能・使用禁止 |
これらを意識できていれば、
文字列を加工・生成する関数は
非常に心強い道具になります。
