スライドショー

【C言語入門】strcpyとstrcpy_sの使い方(文字列のコピー)

strcpyって使ってますか?

strcpyは文字列型データをコピーするために使用する関数です。

文字列はchar型の配列やchar型のポインタとして扱われます。

文字列型のデータを数値型のデータのように「=」記号を使って代入コピーしようとしても、配列の場合は代入できなかったり、ポインタの場合はアドレス先をコピーすることになるなど、意図通りにならないので注意が必要です。

この記事では、文字列のコピーについて

  • 文字列の代入について
  • strcpyの使い方について
  • strcpyを使用する上での注意
  • strcpy_sの使い方

など、よくやりがちなコピーの内容から、関数を使った文字列のコピーについてまで解説していきます。

今回は文字列のコピーについて、使い方をわかりやすく解説します!

文字列の代入について

文字列型のデータのコピーは数値型のデータのように「=」記号を使って代入コピーしようとしても、意図通りになりません。

配列の場合は代入することができません。ポインタの場合はアドレス先をコピーすることになります。

サンプルコードで確認していきましょう。

#include <stdio.h>
 
int main(void) {
    char str1[16] = "Hello World!";
    char str2[16];
    
    /* 配列の代入は不可
    str2 = str1;
    */
    
    char *ptr1, *ptr2;
    ptr1 = str1; // char型ポインタにchr型配列のアドレスを代入
    
    // 文字列のアドレスのコピー(浅いコピー)
    ptr2 = ptr1;
    printf("ptr2の文字列は: %s\n", ptr2);
    printf("ptr1のアドレス: %p, ptr2のアドレス: %p\n", ptr1, ptr2);
    
    str1[0] = 'h'; 
    printf("ptr1の文字列は: %s\n", ptr1);
    printf("ptr2の文字列は: %s\n", ptr2);
    
    return 0;
}

実行結果:

ptr2の文字列は: Hello World!
ptr1のアドレス: 0x7ffce1776b50, ptr2のアドレス: 0x7ffce1776b50
ptr1の文字列は: hello World!
ptr2の文字列は: hello World!

このサンプルコードでは、まずchar型配列「str1」を「=」記号を使って「str2」に代入しようとしています。

しかし、コンパイルエラーが発生するので コメントアウトしています。

次にchar型のポインタ「ptr1」に「str1」のアドレスを代入しています。

「ptr1」のアドレスを「=」記号を使って「ptr2」に代入しています。

結果「ptr1」と「ptr2」はアドレスが同じで、「ptr2」は「ptr1」の値と同じ値を表示しています。

この場合、「ptr1」は「str1」のアドレスですので、「str1」の最初の文字を「H」から「h」に変更すると「ptr1」の表示も変わりますが、「ptr2」の表示も変わりますので注意が必要です。

strcpyの使い方について

前述の理由で文字列のコピーには「=」記号を使った代入ではなく、strcpy関数を使用するのが一般的です。

strcpy関数はヘッダーファイル「string.h」をインクルードして使用します。strcpyの第1引数にはコピー先のアドレス、第2引数にはコピー元のアドレスを記入します。

それではサンプルコードで確認していきましょう。

#include <stdio.h>
#include <string.h>
 
int main(void) {
    char str1[16] = "Hello World!";
    char str2[16];
    
    // 文字列のコピー
    strcpy(str2, str1);
    printf("str2の文字列は: %s\n", str2);
    
    return 0;
}

実行結果:

str2の文字列は: Hello World!

このサンプルコードでは文字型配列「str1」を「str2」へstrcpy関数を使ってコピーしています。

strcpyを使用する上での注意

strcpyで文字列をコピーする場合、バッファーオーバーフローについて注意する必要があります。

バッファオーバーフローのバッファとは、メモリ上に確保する領域のことを指します。

オーバーフローとは、バッファがあふれた状態を指します。メモリ上に確保されたバッファがあふれ、意図しない動作を引き起こすことがあります。

例えば、隣接したメモリのアドレスに不正に上書きするなどです。

C言語では変数で確保したバイト数以上に、値を代入することができてしまいます。

サンプルコードで確認しましょう。

#include <stdio.h>
#include <string.h>
 
int main(void) {
    char str1[16] = "Hello World!";
    char str2[4];
    
    // 文字列のコピー
    strcpy(str2, str1);
    printf("str2の文字列は: %s\n", str2);
    
    return 0;
}

実行結果:

str2の文字列は: Hello World!

先ほどのサンプルコードと同じように、文字型配列「str1」を「str2」へstrcpy関数を使ってコピーしています。

ですが、str1のバイト数が16に対して、str2で確保したメモリのバイト数は4で足りていません。

C言語では確保したバイト数が足りなくてもそのまま処理してしまいます。

これが原因で意図しないメモリの書き込みが発生してしまうこともありますので、注意しましょう!

strcpy_sの使い方

Visual StudioのC++の環境でコンパイルする際には注意が必要です。

VisualC++ではstrcpy関数を使用するとコンパイルエラーが発生し、strcpy_s関数を使うようにメッセージが表示される場合があります。

strcpy_s関数を使う場合は、文字列で受け取るメモリ領域のサイズを指定する必要があります。

strcpy_sの第1引数にはコピー先のアドレス、第2引数にはコピー先のバッファサイズ、第3引数にはコピー元のアドレスを記入します。

strcpy_s(コピー先のアドレス, コピー先のバッファサイズ, コピー元のアドレス)

サンプルコードで確認しましょう。

#include <stdio.h>
#include <string.h>

int main(void) {
    char str1[16] = "Hello World!";
    char str2[16];

    // 文字列のコピー
    strcpy_s(str2, 16, str1);
    printf("str2の文字列は: %s\n", str2);

    system("pause");    // 出力表示のための一時停止

    return 0;
}

実行結果:

str2の文字列は: Hello World!
続行するには何かキーを押してください . . .

文字列の使い方総まとめ

この記事では紹介しきれなかった文字列のいろいろな使い方を次の記事にまとめているので、ぜひ確認してください!

【C言語入門】文字列とは?文字列の使い方総まとめ
更新日 : 2019年5月20日

まとめ

ここでは、文字列をコピーする方法について説明しました。

「=」記号を使った代入では意図通りにコピーすることができない場合があります。

strcpy関数を使って文字列をコピーすることができるように、この記事を何度も参考にして下さいね!

LINEで送る
Pocket

ITエンジニアへ転職したい方におすすめ

自分を評価してくれる企業に転職して年収を上げたい! 自分のスキルにあった独自案件を知りたい!
エンジニアは今もっとも注目されている職業の1つ。エンジニアになって年収を増やしたい方や、あなたのスキルに見合った企業へ転職したいエンジニアの方も多いですよね。

しかし、大手の転職媒体は扱う求人数が多くても、誰もが登録しているので競争率もかなり高くなっています。そのため、あなたの条件に見合った企業を見つけても転職するためには、相応の努力とスキルが必要となります。

こういった媒体では、未経験からエンジニアを目指す方やエンジニア歴2〜3年で転職を考えている方にとって、最適な転職環境とはいえません。

そこでオススメしたいのが、未経験者や若手エンジニア向けの独自案件を多く掲載している「侍ワークス」です。

侍ワークスは、独自案件を多く掲載しているだけでなく、

・応募から就業まで一貫したサポート

・就業後もアフターフォロー

といった経験の浅い方や初めてエンジニアを目指す方にも安心のフォロー体制が整っています。もちろん登録は完全無料!しかも案件を見るだけなら登録も不要です。

まずは、お気軽にどんな求人があるか見てみてください。あなたにピッタリの企業がきっと見つかりますよ! 侍ワークスの求人情報を見る

書いた人

長野 透

長野 透

熊本在住のフリープログラマ兼ライターです。C/C++/C#、Java、Python、HTML/CSS、PHPを使ってプログラミングをしています。専門は画像処理で最近は機械学習、ディープラーニングにはまっています。幅広くやってきた経験を活かしてポイントをわかりやすくお伝えしようと思います。
お問合せはこちらでも受け付けています。
[email protected]