【C++】stringとchar配列の違いとは?|文字列の扱い方を整理

サムネイル画像 C++

今回は、C++でよく混乱しやすい「stringとchar配列の違い」について解説していきます。

「C言語ではchar配列を使っていたけど、C++ではstringって何が違うの?」
「文字列を関数に渡したらエラーになった…」
「結局どっちを使えばいいの?」

こんな疑問はありませんか?

C言語からC++に入ると、最初は char str[] をそのまま使いたくなりますよね。ですが、C++では std::string がかなり便利で、文字列の連結・代入・長さ取得などがかなり楽になります。

この記事を読み終えると、あなたはstringとchar配列の意味・違い・使い分け・変換方法・初心者がハマりやすいエラーをしっかり理解できるようになると思いますので、ぜひ最後まで読んでいただけると嬉しいです。

stringとchar配列の違いとは?

まず結論からいうと、char配列は文字を並べた配列で、stringはC++標準ライブラリの文字列クラスです。

  • char配列:C言語からある古い形の文字列
  • string:C++で使いやすく設計された文字列
  • char配列:終端の \0 を意識する必要がある
  • string:長さ取得や連結が簡単

つまり、見た目はどちらも「文字列」ですが、中身の扱い方はかなり違います。

なぜこの違いを理解する必要がある?

C言語の感覚のままchar配列を使っていると、代入や連結のたびに手間が増えたり、関数に渡す時に型が合わずエラーになったりしやすいです。

特に初心者がつまずきやすいのは、「char配列は配列」「stringはクラス」という点です。この違いがあるので、代入の書き方や関数への渡し方も変わります。

配列やメモリまわりの感覚がまだ曖昧な方は、ポインタの記事sizeofの記事もあわせて読むと理解しやすいです。

char配列の基本

まずはchar配列の例です。これはC言語でもよく見る書き方ですね。

▼main.cpp


#include <iostream>

int main() {
    char name[] = "Kashiros";

    std::cout << name << "\n";
    return 0;
}

実行結果

Kashiros

このように、char配列でも文字列として表示できます。ただし、これはあくまで文字の配列なので、配列としての制約を受けます。

stringの基本

次にC++らしい書き方である std::string です。使うには #include <string> が必要です。

▼main.cpp


#include <iostream>
#include <string>

int main() {
    std::string name = "Kashiros";
    std::string message = "Hello " + name;

    std::cout << message << "\n";
    std::cout << name.size() << "\n";
    return 0;
}

実行結果

Hello Kashiros
8

stringはこのように、連結や長さ取得がかなり自然に書けます。C++初心者のうちは、まずこちらに慣れる方がかなり楽です。

「こう書くとエラー → こう直す」:stringをchar配列の感覚で使うとハマる

C言語の感覚のまま「文字列は全部同じだろう」と思っていると、ここでハマりやすいです。

たとえば、const char* を受け取る関数にstringをそのまま渡すと、環境によってはコンパイルエラーになります。

▼main.cpp


#include <iostream>
#include <string>

void PrintText(const char* text) {
    std::cout << text << "\n";
}

int main() {
    std::string name = "Player";
    PrintText(name);
    return 0;
}

実行結果

コンパイルエラー
const char* を受け取る関数に std::string をそのまま渡せない

こういう時は、c_str() を使ってstringを const char* に変換します。

▼main.cpp


#include <iostream>
#include <string>

void PrintText(const char* text) {
    std::cout << text << "\n";
}

int main() {
    std::string name = "Player";
    PrintText(name.c_str());
    return 0;
}

実行結果

Player

この c_str() はかなりよく使うので、stringを学ぶなら早めに覚えておくのがおすすめです。関数の宣言まわりが不安な方は、プロトタイプ宣言の記事も参考になると思います。

【重要】私が実際にstringとchar配列で困った体験談

私も自主制作のゲームで、UIに表示する文字列を最初は全部char配列で管理していたことがあります。C言語に近い感覚で書けるので、最初はその方が分かりやすいと思っていたからです。

ですが、スコア表示やHP表示のように、数字を文字列にしてつなげたい場面が増えると、一気に面倒になりました。char配列だと連結や更新のたびに気を使いますし、関数に渡す時も型の違いで止まりやすかったです。

その後、表示用の文字列はstringを基本にして、C形式の文字列が必要な所だけ c_str() を使う形にしたらかなり整理しやすくなりました。個人的には、「普段はstring、必要な時だけchar配列やconst char*」がかなり扱いやすいと感じています。

stringとchar配列使用時のよくある失敗例と対処法

1. char配列にあとから文字列を代入しようとする

char配列は配列なので、後から丸ごと代入はできません。

  • 失敗例:char text[10] = "abc"; の後に text = "xyz"; と書く
  • 対処法:再代入を多用するならstringを使う

2. stringをconst char*の関数にそのまま渡す

先ほどの例のように、APIや古い関数では const char* を要求することがあります。

  • 失敗例:PrintText(name);
  • 対処法:name.c_str() を使う

3. char配列とポインタを同じだと思ってしまう

似て見える場面はありますが、完全に同じではありません。特に sizeof を使う時は結果が変わることがあります。

  • 失敗例:char配列とcharポインタで同じサイズが取れると思う
  • 対処法:配列・ポインタ・stringは別物として考える

実践例:ゲームの表示文字列を作るならstringが便利

たとえば、ゲーム中に「HP: 120」のような表示文字列を作りたい時は、stringの方がかなり自然です。

▼main.cpp


#include <iostream>
#include <string>

void DrawText(const char* text) {
    std::cout << text << "\n";
}

int main() {
    int hp = 120;
    std::string message = "HP: " + std::to_string(hp);

    DrawText(message.c_str());
    return 0;
}

実行結果

HP: 120

このように、stringで文字列を組み立てて、最後に必要なら c_str() で渡すのがかなり分かりやすいです。

注意点

  • 普段の文字列処理はstringの方がかなり書きやすい
  • char配列はC言語互換や古いAPIとのやり取りで今でも出てくる
  • c_str() で得たポインタ先を書き換える前提では使わない
  • string・配列・ポインタは似て見えても別物として整理する

もし「どこで型がズレているのか分からない」「関数に渡した時に何が起きているのか見えない」という時は、Visual Studioでのデバッグ方法もかなり役立ちます。

まとめ

  • char配列は文字の配列、stringはC++の文字列クラス
  • 普段の文字列操作はstringの方がかなり便利
  • 古い関数やAPIでは const char* が必要なことがある
  • その時は c_str() で変換する
  • C言語の感覚のまま扱うと、代入や関数呼び出しでハマりやすい

個人的には、「C++ではまずstringを基本にして、必要な時だけchar配列やconst char*を使う」のがおすすめです。この整理ができるだけで、文字列まわりはかなり分かりやすくなります。

関連記事