記事内にはプロモーションが含まれています

【C++】文字列と数値を相互変換する方法まとめ

【C++】文字列と数値を相互変換する方法まとめ C++

C++でアプリケーションを開発していると、ユーザーからの入力を計算に利用したり、計算結果をログとして画面に表示したりするために「文字列」と「数値」を相互に変換する処理が頻繁に必要になります。

しかし、C++には古くからのC言語由来の方法(atoisprintf)と、モダンな標準ライブラリ(std::stoistd::format)が混在しており、「自分の開発環境と要件において、どの方法が最適なのか」と迷ってしまう方も多いのではないでしょうか。

特に、変換時のエラーチェックや16進数の扱い、表示を整えるための0埋めなどは、実装方法によって安全性やパフォーマンスが大きく変わります。

この記事では、現代のC++開発における文字列・数値変換の主要な手法を、C++20/23/26環境までを見据えて詳しく解説します。

安全性、パフォーマンス、可読性のバランスを考慮したコード選びに役立ててください。

【本記事の信頼性】
プロフィール
執筆者:マヒロ
  • 執筆者は元エンジニア
  • SES⇒大手の社内SE⇒独立
  • 現在はプログラミングスクールを運営
  • モットーは「利他の精神」
💻 本記事の検証環境(2026年2月確認)
  • OS:Windows 11 / macOS Sequoia
  • IDE:Visual Studio / VS Code / IntelliJ IDEA
  • その他:Chrome DevTools / 各言語最新安定版

※本メディアでは、上記環境にてコードの動作と情報の正確性を検証済みです。

文字列から数値へ変換する主要なメソッド

文字列(std::string)を数値(intdouble)に変換する場合、標準ライブラリの変換関数を使用するのが一般的です。

ただし、C++11以降の「手軽な例外ベースの関数」と、C++17以降の「高性能な非例外ベースの関数」では設計思想が大きく異なります。

ここでは、用途に合わせた2つのアプローチについて、具体的な実装方法を見ていきましょう。

1. 手軽に変換する(std::stoi / std::stod)

C++11で導入された std::stoi(string to integer)系は、最も広く普及している変換方法です。

#include <iostream>
#include <string>

int main() {
    std::string strValue = "12345";
    
    // 文字列をint型に変換(失敗時は例外が発生)
    int num = std::stoi(strValue);

    std::cout << "変換後の数値: " << num << std::endl;
    return 0;
}

この手法は、文字列の先頭にある空白を自動でスキップする機能を持ち、記述も非常に簡潔です。

ただし、変換に失敗すると例外(std::invalid_argument など)を投げるため、後述するエラー処理の節で解説するように try-catch による保護が推奨されます。

2. 高性能・安全に変換する(std::from_chars)

C++17で導入された std::from_chars は、例外を投げず、動的メモリ確保も行わない、極めて高速かつ安全な変換手段です。

パフォーマンスが要求されるシステムや、例外を避けたい環境ではこちらが有力な選択肢です。

#include <iostream>
#include <charconv> // std::from_chars に必要
#include <string_view>
#include <system_error>

int main() {
    std::string_view str = "3.14159";
    double val;

    // 例外を投げず、戻り値で成否を返す
    auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), val);

    if (ec == std::errc{}) {
        std::cout << "変換成功: " << val << std::endl;
    } else {
        std::cerr << "変換失敗" << std::endl;
    }
    return 0;
}

浮動小数点数変換の注意点
std::stodstd::from_chars で小数を扱う場合、変換結果はdouble型で表現可能な範囲と精度に制限される点に注意してください。

IEEE 754規格に基づく丸め誤差が発生し得るため、厳密な数値計算を必要とする読者は、変換後の誤差の考慮が不可欠です。

数値から文字列へ変換する方法と書式指定

数値を表示や保存のために文字列へ変換する際、以前のC++では std::stringstream などが多用されてきましたが、現在は「簡潔さ」か「柔軟な書式指定」かで手法を使い分けるのが合理的です。

簡易的な変換(std::to_string)

デバッグ用のログ出力などで、書式にこだわらずサクッと変換したい場合に有力です。

#include <iostream>
#include <string>

int main() {
    int count = 100;
    std::string s = std::to_string(count);
    std::cout << s << std::endl;
    return 0;
}

std::to_string は非常に手軽ですが、浮動小数点数を渡すと処理系によって "1.200000" のように不要な桁が出力されるなど、出力形式を制御できないという制約があります。

また、内部でバッファ確保を行うため、極限のパフォーマンスを求めるループ内などでは注意が必要です。

書式を指定する有力な選択肢(std::format)

「001」のような0埋め(ゼロパディング)や、特定の桁数での表示が必要な場合、C++20で導入された std::format が有力な選択肢となります。

#include <iostream>
#if __has_include(<format>)
#include <format> // C++20以上、かつ対応OS/コンパイラが必要
#endif
#include <string>

int main() {
    int id = 7;
    double price = 120.5;

    // 対応している環境であれば、Python風の簡潔な記述が可能
#ifdef __cpp_lib_format
    std::string s1 = std::format("{:03}", id);   // 3桁で0埋め
    std::string s2 = std::format("{:.2f}", price); // 小数点第2位まで
    std::cout << "ID: " << s1 << ", Price: " << s2 << std::endl;
#else
    std::cout << "std::format は現在の環境でサポートされていません" << std::endl;
#endif
    return 0;
}

導入時の注意点
std::format は非常に強力ですが、C++20規格であり、GCC(libstdc++ 13以前)など一部の環境では未実装または不完全な場合があります。

そのような環境では、従来の std::stringstream や、std::format のベースとなった外部ライブラリの {fmt} を活用するのが現実的なベストプラクティスです。

16進数と数値の相互変換テクニック

メモリ情報の表示などで頻出する16進数変換も、標準関数の引数やフォーマット指定子の工夫でスマートに処理できます。

16進数文字列を数値にする

std::stoi の第3引数に基数 16 を渡すことで、”FF” や “0x10” といった文字列を解析できます。

#include <iostream>
#include <string>

int main() {
    std::string hexStr = "0xFF";
    // 第3引数に16を指定(0xプレフィックスも自動解釈)
    int value = std::stoi(hexStr, nullptr, 16);
    std::cout << value << std::endl; // 255
    return 0;
}

数値を16進数文字列にする

前述の std::format が使える環境であれば、最もスマートに記述できます。

#ifdef __cpp_lib_format
// 小文字の16進数
std::string s_low = std::format("{:x}", 255); // "ff"
// #フラグによるプレフィックス(0x)を含めた全体幅指定
std::string s_high = std::format("{:#06X}", 255); // "0x00FF"
#endif

{:#06X} という指定は、# フラグで付与される 0x の2文字を含めて全体を6文字にするという意味です。

このように、複雑な書式も一括で定義できるのがモダンなC++の強みです。

変換の安全性とエラー処理の使い分け

変換処理において最も考慮すべきは「不正な入力(”abc” など)」への対処です。
C++には大きく分けて2つの設計思想があります。

1. 例外処理(try-catch)を利用する

std::stoi 系を使う場合、エラーは例外として通知されます。集中管理したい場合には有効です。

try {
    int num = std::stoi("invalid");
} catch (const std::invalid_argument& e) {
    std::cerr << "解釈不能な文字列です" << std::endl;
} catch (const std::out_of_range& e) {
    std::cerr << "型の許容範囲を超えています" << std::endl;
}

2. ステータスチェックを利用する(例外を投げない)

パフォーマンスを重視する場合や、エラーが頻発する可能性がある入力を扱うなら、std::from_chars のような戻り値でエラーを返すAPIを選びます。

「例外コストを嫌う設計」が求められる実務の現場では、C++17以降であれば std::from_chars を優先的に使用することが現代的なアプローチの一つとして定着しつつあります。

C++のスキルを活かして年収を上げる方法

以上、C++で文字列と数値を相互変換する方法について解説しました。

なお、C++のスキルがある場合には、「転職して年収をアップさせる」「副業で稼ぐ」といった方法を検討するのがおすすめです。

C++を扱えるエンジニアは希少価値が高いため、転職によって数十万円の年収アップはザラで、100万円以上年収が上がることも珍しくありません。

なお、転職によって年収を上げたい場合は、エンジニア専門の転職エージェントサービスを利用するのが最適です。
今すぐ転職する気がなくとも、とりあえず転職エージェントに無料登録しておくだけで、スカウトが届いたり、思わぬ好待遇の求人情報が送られてきたりするというメリットがあります。
併せて、副業案件を獲得できるエージェントにも登録しておくと、空いている時間を活かして稼げるようなC++の案件を探しやすくなります。

転職エージェントも副業エージェントも、登録・利用は完全無料なので、どんな求人や副業案件があるのか気になる方は、気軽に利用してみるとよいでしょう。
エンジニアのキャリア・スキルアップ相談窓口
当ブログの読者に選ばれている、実績豊富な転職エージェントを厳選しました。
【転職】年収・環境を改善したい
年収アップにこだわりたい方 (平均アップ額138万円の実績)
未経験・経験者問わず幅広く探したい方
業界に精通した担当者に相談したい方
ゲーム業界への転職を志望する方
エンジニア未経験からキャリアを築く方
【独立】フリーランスとして稼ぎたい
国内最大級のフリーランス案件数から比較したい方
週1〜3日など柔軟な働き方を希望する方
【学習】スキルに不安のある方向け(格安スクール「デイトラ」)