C#: 文字列⇄数値変換の方法を解説(Parse/TryParse/ToString)

C#で文字列と数値を相互に変換する場面は、フォーム入力の検証、ファイルやAPIの入出力、ログ出力や画面表示など多岐にわたります。

本稿では、初心者の方でも迷わないように、Parse/TryParse/ToStringの使い分けから、例外やロケール対応(NumberStyles/CultureInfo)まで、具体例と実行結果付きで丁寧に解説します。

C#の文字列⇄数値変換の基本(Parse/TryParse/ToString)

文字列→数値の基本方針と選び方(ParseとTryParseの違い)

文字列から数値へは大きく2通りの入り口があります。

  • Parse系: int.Parse, double.Parse, decimal.Parse など。失敗時は例外を投げます。
  • TryParse系: int.TryParse, double.TryParse, decimal.TryParse など。失敗時は例外を投げず、boolで成否を返します。

ユーザー入力や外部データのように「失敗する可能性がある」場合はTryParseを優先し、事前に「必ず正しい形式だ」と分かっている場合のみParseを使うのが基本方針です。

以下は違いが分かる最小例です。

C#
using System;
using System.Globalization;

class Program
{
    static void Main()
    {
        string ok = "123";
        string ng = "abc";

        // Parse: 成功 -> 値、失敗 -> 例外
        Console.WriteLine(int.Parse(ok)); // 123
        try
        {
            Console.WriteLine(int.Parse(ng));
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.GetType().Name); // 何の例外かを出力
        }

        // TryParse: 成否をboolで返し、失敗しても例外なし
        bool success = int.TryParse(ng, out int value);
        Console.WriteLine($"TryParse={success}, value={value}");
    }
}
実行結果
123
FormatException
TryParse=False, value=0

数値→文字列の基本方針(ToStringと書式指定の概要)

数値から文字列へはToStringが基本です。

ToString()は引数に「書式指定子」と「カルチャ情報」を取れます。

  • num.ToString("N2", CultureInfo.GetCultureInfo("en-US")) のように書くと、桁区切りや小数点の位置、ロケールごとの表記に合わせて文字列化できます。
  • 書式指定子には、標準書式(G, N, F, C, Pなど)とカスタム書式(例: #,0.00, 00000)があります。

Parseの使い方と注意点(int.Parse/double.Parse/decimal.Parse)

Parseが投げる例外(FormatException/OverflowException)

Parseは「形式が不正」や「範囲外」のときに例外を投げます。

C#
using System;

class Program
{
    static void Main()
    {
        // 形式が不正 -> FormatException
        try
        {
            var x = int.Parse("12x3");
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.GetType().Name);
        }

        // 範囲外 -> OverflowException (intの最大値は 2,147,483,647)
        try
        {
            var y = int.Parse("2147483648");
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.GetType().Name);
        }
    }
}
実行結果
FormatException
OverflowException

前後の空白やタブの扱い(Trimの活用)

多くのParseは前後の空白(タブや改行を含む)を既定で許容しますが、入力が不安定な場合はTrim()で明示的に削除しておくと安全です。

C#
using System;

class Program
{
    static void Main()
    {
        string s = "\t  123 \r\n";
        int n1 = int.Parse(s);          // OK: 既定で前後の空白を許容
        int n2 = int.Parse(s.Trim());   // もちろんOK

        Console.WriteLine(n1);
        Console.WriteLine(n2);
    }
}
実行結果
123
123

符号・小数点・桁区切りの解釈(NumberStyles/CultureInfo)

数値の表記はカルチャ(ロケール)によって異なります。

例えばドイツ(de-DE)では小数点が,、桁区切りが.です。

CultureInfoNumberStylesを併用すると、意図通りに解釈できます。

C#
using System;
using System.Globalization;

class Program
{
    static void Main()
    {
        // de-DE: "1.234,56" => 1234.56
        var de = new CultureInfo("de-DE");
        double d = double.Parse("1.234,56", de);
        Console.WriteLine(d);

        // en-USで桁区切りと符号を許容してintを解釈
        var us = new CultureInfo("en-US");
        int i = int.Parse("-1,234", NumberStyles.Integer | NumberStyles.AllowThousands, us);
        Console.WriteLine(i);
    }
}
実行結果
1234.56
-1234

要点として、NumberStylesにはAllowLeadingSign, AllowThousands, AllowDecimalPoint, Currency, Anyなどがあり、何を許容するか細かく指定できます。

カルチャに応じて適切なCultureInfoを渡してください。

TryParseの使い方とベストプラクティス

TryParseの基本シグネチャと戻り値(bool)

TryParseは以下の2系統がよく使われます。

  • bool int.TryParse(string? s, out int result)
  • bool int.TryParse(string? s, NumberStyles style, IFormatProvider? provider, out int result)

成功時はtrueと変換後の値、失敗時はfalseとデフォルト値(数値型は0)が返ります。

入力検証の定番パターン(ifとTryParse)

ユーザー入力検証の基本形です。

例として、複数の入力文字列を検証します。

C#
using System;
using System.Globalization;

class Program
{
    static void Main()
    {
        var us = new CultureInfo("en-US");
        string[] inputs = { "42", "  99 ", "1,234", "abc" };

        foreach (var s in inputs)
        {
            // 桁区切りを許容して解析
            bool ok = int.TryParse(s, NumberStyles.Integer | NumberStyles.AllowThousands, us, out int value);
            if (ok)
            {
                Console.WriteLine($"OK: {s} -> {value}");
            }
            else
            {
                Console.WriteLine($"NG: {s} は整数として無効です");
            }
        }
    }
}
実行結果
OK: 42 -> 42
OK:   99  -> 99
OK: 1,234 -> 1234
NG: abc は整数として無効です

NumberStyles/CultureInfoを指定したTryParse

通貨記号や各国の区切りに対応したい場合は、NumberStyles.Currencyや適切なCultureInfoを指定します。

C#
using System;
using System.Globalization;

class Program
{
    static void Main()
    {
        bool okJp = decimal.TryParse("¥1,234", NumberStyles.Currency, new CultureInfo("ja-JP"), out decimal yen);
        bool okDe = decimal.TryParse("1.234,56 €", NumberStyles.Currency, new CultureInfo("de-DE"), out decimal euro);
        bool okGb = decimal.TryParse("£100.50", NumberStyles.Currency, new CultureInfo("en-GB"), out decimal gbp);

        Console.WriteLine($"ja-JP: {okJp}, {yen}");
        Console.WriteLine($"de-DE: {okDe}, {euro}");
        Console.WriteLine($"en-GB: {okGb}, {gbp}");
    }
}
実行結果
ja-JP: True, 1234
de-DE: True, 1234.56
en-GB: True, 100.50

ToStringによる数値→文字列変換のやり方

標準書式指定子(G/N/F/C/Pなど)の使い分け

代表的な標準書式の概要です。

指定子説明
G一般的な最短表現(最も短い形式で表現)
N数値(桁区切りあり、小数点以下の桁数を指定可能。例: N0, N2
F固定小数点(桁区切りなし、小数点以下の桁数を指定可能。例: F2
C通貨(ロケールに応じた通貨記号を付与)
Pパーセント(値を100倍して % を付与、小数点以下桁数を指定可能)
D整数の10進数表記(整数型専用。桁数指定可能。例: D4 → 0012)
X整数の16進数表記(整数型専用。大文字/小文字は X / x で切替)

実例で確かめます。

C#
using System;
using System.Globalization;

class Program
{
    static void Main()
    {
        var us = new CultureInfo("en-US");
        double x = 1234.567;
        double ratio = 0.1234;

        Console.WriteLine(x.ToString("G", us));   // 一般
        Console.WriteLine(x.ToString("N2", us));  // 桁区切り + 小数2桁
        Console.WriteLine(x.ToString("F2", us));  // 固定小数2桁
        Console.WriteLine(x.ToString("C2", us));  // 通貨(小数2桁)
        Console.WriteLine(ratio.ToString("P1", us)); // パーセント(小数1桁)
    }
}
実行結果
1234.567
1,234.57
1234.57
$1,234.57
12.3%

整数のゼロ埋めや16進表現も簡単です。

C#
using System;

class Program
{
    static void Main()
    {
        int id = 42;
        Console.WriteLine(id.ToString("D5")); // 00042
        Console.WriteLine(id.ToString("X"));  // 2A (16進)
    }
}
実行結果
00042
2A

カスタム書式(桁区切り, 小数点桁数, 0埋め)

より細かい制御が必要なときはカスタム書式を使います。

0は必ず表示、#はあれば表示、,は桁区切り、.は小数点です。

C#
using System;
using System.Globalization;

class Program
{
    static void Main()
    {
        var us = new CultureInfo("en-US");
        double amount = 1234.5;
        int seq = 42;

        Console.WriteLine(amount.ToString("#,0.00", us)); // 1,234.50
        Console.WriteLine(amount.ToString("0.###", us));  // 1234.5
        Console.WriteLine(seq.ToString("00000"));         // 00042
    }
}
実行結果
1,234.50
1234.5
00042

CultureInfoでロケール別の文字列を出力

同じ値でもカルチャにより見た目が変わります。

C#
using System;
using System.Globalization;

class Program
{
    static void Main()
    {
        double v = 1234.56;
        decimal price = 1234m;

        var us = new CultureInfo("en-US");
        var de = new CultureInfo("de-DE");
        var jp = new CultureInfo("ja-JP");

        // 数値(N2)
        Console.WriteLine(v.ToString("N2", us)); // en-US
        Console.WriteLine(v.ToString("N2", de)); // de-DE
        Console.WriteLine(v.ToString("N2", jp)); // ja-JP

        // 通貨(C)
        Console.WriteLine(price.ToString("C", us)); // en-US
        Console.WriteLine(price.ToString("C", de)); // de-DE
        Console.WriteLine(price.ToString("C", jp)); // ja-JP (円は小数なし)
    }
}
実行結果
1,234.56
1.234,56
1,234.56
$1,234.00
1.234,00 €
¥1,234

型別の注意点と精度(int/long/float/double/decimal)

int/longの範囲とオーバーフロー対策

整数型は取り得る範囲が決まっています。

Parseは範囲外をOverflowExceptionとして検出します。

自前演算のオーバーフローはcheckedで検出できます。

C#
using System;

class Program
{
    static void Main()
    {
        Console.WriteLine($"int:   {int.MinValue} .. {int.MaxValue}");
        Console.WriteLine($"long:  {long.MinValue} .. {long.MaxValue}");

        try
        {
            checked
            {
                int x = int.MaxValue;
                x += 1; // ここでOverflowException
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.GetType().Name);
        }
    }
}
実行結果
int:   -2147483648 .. 2147483647
long:  -9223372036854775808 .. 9223372036854775807
OverflowException

float/doubleの丸め誤差とToStringの注意点

float/doubleは2進浮動小数のため、10進小数を正確に表せない場合があります。

0.1 + 0.2の例が典型です。

表示書式により誤差が見えたり隠れたりします。

C#
using System;
using System.Globalization;

class Program
{
    static void Main()
    {
        var inv = CultureInfo.InvariantCulture;
        double d = 0.1 + 0.2;

        Console.WriteLine(d.ToString("G", inv));  // 一般表記(見た目は0.3)
        Console.WriteLine(d.ToString("R", inv));  // 厳密(ラウンドトリップ)
        // 近年の.NETでは "G17" も厳密表現として有効
        Console.WriteLine(d.ToString("G17", inv));
    }
}
実行結果
0.3
0.30000000000000004
0.30000000000000004

表示上は四捨五入されても中身はわずかにズレるため、金額など誤差が許されない用途ではdecimalを使います。

decimalでの金額計算とParse/TryParseのコツ

decimalは10進小数を高精度で扱えるため、金額・個数・率などに適しています。

通貨の解析にはNumberStyles.Currencyと適切なCultureInfoを組み合わせます。

C#
using System;
using System.Globalization;

class Program
{
    static void Main()
    {
        // 計算の安定性
        decimal a = 0.1m + 0.2m;
        Console.WriteLine(a); // 0.3

        // 解析のコツ
        var us = new CultureInfo("en-US");
        bool ok = decimal.TryParse("$1,234.50", NumberStyles.Currency, us, out decimal price);
        Console.WriteLine($"{ok}, {price}");
    }
}
実行結果
0.3
True, 1234.50

エラー対策とまとめ(初心者が押さえるポイント)

よくある失敗と対処法(全角・空白・桁区切り)

実務では入力が「きれい」とは限りません。

よくある落とし穴と対処の要点です。

  • 全角数字・全角記号: そのままでは失敗することがあります。互換正規化(FormKC)で半角に寄せてから解析すると安定します。
  • 前後や途中の空白: Trim()NumberStylesで許容。意図しない空白が混ざる場合は前処理で除去を検討します。
  • 桁区切り・通貨記号: NumberStyles.AllowThousandsNumberStyles.Currency を使い、CultureInfoを正しく指定します。

例: 全角の数字とカンマを正規化してから解析するパターンです。

C#
using System;
using System.Globalization;
using System.Text;

class Program
{
    static void Main()
    {
        string raw = " 123,456 "; // 全角空白・全角数字・全角カンマ
        string normalized = raw.Normalize(NormalizationForm.FormKC).Trim(); // 半角化 + 前後空白除去

        bool ok = int.TryParse(
            normalized,
            NumberStyles.Integer | NumberStyles.AllowThousands,
            new CultureInfo("ja-JP"),
            out int value);

        Console.WriteLine($"{ok}, {value}");
    }
}
実行結果
True, 123456

使い分けの結論(Parse/TryParse/ToString)

  • 文字列→数値: 未検証の入力や外部データはTryParseで安全に。形式保証済みの内部データのみParseを使う。
  • 数値→文字列: 画面やログの表示はToStringに書式を付け、必要に応じてCultureInfoを明示する。金額はdecimalで扱い、通貨書式(C)を活用する。
  • ロケール差異: 解析・表示の双方でCultureInfoを意識する。異文化圏のデータやAPI連携では特に重要。

覚えておきたいキーワード(NumberStyles/CultureInfo/書式指定子)

  • NumberStyles: 入力の許容範囲(符号、桁区切り、小数点、通貨記号、空白など)を制御。
  • CultureInfo: 小数点や桁区切り、通貨/%記号の位置など、ロケール固有のルールを提供。
  • 書式指定子: 標準(G/N/F/C/P/D/Xなど)とカスタム(#,0.00や00000など)で出力の見た目を制御。

まとめ

C#の文字列⇄数値変換は、Parse/TryParse/ToStringの3本柱を場面に応じて使い分けるのが基本です。

未検証の入力はTryParseで堅牢に受け止め、内部的に正しいと分かっている場合のみParseを使います。

表示はToStringに書式とCultureInfoを合わせて、読みやすく・誤解のない表記に整えます。

特に、金額はdecimal、各国表記はCultureInfo、入力の多様性にはNumberStylesや正規化で備えると安心です。

これらのポイントを押さえれば、日常の開発で困ることは大幅に減るはずです。

クラウドSSLサイトシールは安心の証です。

URLをコピーしました!