C# ‘System.FormatException: Input string was not in a correct format.’ の原因と解決方法

System.FormatException: Input string was not in a correct format. とは

このエラーは、文字列を異なるデータ型(整数、日付、浮動小数点数など)に変換しようとした際に、その文字列が変換先の型として有効な形式ではない場合に発生します。ユーザー入力やファイルからのデータ読み込みで頻繁に見られる一般的なエラーです。

文字列を数値や日付などの型に変換しようとしたとき、その文字列の形式が不正だとFormatExceptionが発生します。

エラーの発生パターン

このエラーは主に以下のようなケースで発生します。

パターン1: 非数値文字列を整数に変換

string input = "abc";
int number = int.Parse(input); // System.FormatException: Input string was not in a correct format.

“abc”は有効な整数形式ではないため、int.Parse()メソッドでint型に変換しようとするとFormatExceptionが発生します。変換前に文字列の内容を検証する必要があります。

string input = "abc";
int number;
if (int.TryParse(input, out number))
{
    Console.WriteLine($"Parsed number: {number}");
}
else
{
    Console.WriteLine("Invalid input for number.");
}

パターン2: 無効な日付形式の文字列を日付に変換

string dateString = "2023-13-01"; // 13月は無効
DateTime date = DateTime.Parse(dateString); // System.FormatException: String was not recognized as a valid DateTime.

“2023-13-01″は月が13であり、有効な日付形式ではありません。DateTime.Parse()厳密な日付形式を期待するため、この形式ではエラーになります。

string dateString = "2023-13-01";
DateTime date;
if (DateTime.TryParse(dateString, out date))
{
    Console.WriteLine($"Parsed date: {date}");
}
else
{
    Console.WriteLine("Invalid input for date.");
}

パターン3: ToString()やstring.Format()での不適切なフォーマット指定子

double value = 123.45;
string formatted = value.ToString("X"); // System.FormatException: Format String can be only "G", "g", "C", "c", "D", "d", "E", "e", "F", "f", "N", "n", "P", "p", "R", "r", "X", "x".

double型には16進数形式指定子"X"が適用できないため、ToString("X")を使用するとFormatExceptionが発生します。適切なフォーマット指定子を使用する必要があります。

double value = 123.45;
string formatted = value.ToString("F2"); // "123.45" (F2は小数点以下2桁の浮動小数点数)
Console.WriteLine(formatted);
FormatExceptionは、入力データの品質管理が不十分な場合に頻繁に発生します。ユーザー入力や外部システムからのデータを受け取る際には、常に形式の検証とエラーハンドリングを考慮しましょう。

根本原因の特定方法

エラーが発生したParse系のメソッド呼び出しの直前で、入力文字列の値をデバッガで確認してください。その文字列が期待する形式と合致しているかを注意深くチェックします。

string problematicString = "Hello"; // 例として不正な文字列

// デバッガでproblematicStringの値を確認
if (int.TryParse(problematicString, out int result))
{
    Console.WriteLine("Success: " + result);
}
else
{
    Console.WriteLine("Failed to parse: " + problematicString);
}

防止策とベストプラクティス

Parseメソッドの代わりに、TryParseメソッドやConvert.ChangeTypeメソッドを使用し、例外処理(try-catchブロック)を適切に実装することで、予期せぬFormatExceptionを防ぐことができます。

string input = "123a"; // 不正な入力

try
{
    int number = int.Parse(input); // ここでFormatExceptionが発生
    Console.WriteLine(number);
}
catch (FormatException ex)
{
    Console.WriteLine("Error: Input string was not in a correct format. " + ex.Message);
}
catch (OverflowException ex)
{
    Console.WriteLine("Error: Number was too large or too small. " + ex.Message);
}
TryParseは例外を発生させずにbool値を返すため、安全に変換を試みられます。try-catch回復可能なエラーを処理するのに適しています。

よくある質問(FAQ)

Q
int.Parse()Convert.ToInt32() の違いは何ですか?
A

int.Parse() は文字列のみを変換し、nullや無効な形式でFormatExceptionをスローします。Convert.ToInt32() はより多くの型を受け入れ、nullの場合は0を返しますが、無効な形式ではFormatExceptionをスローします。

Q
数値のカンマ区切り(例: “1,234”)を変換するにはどうすればよいですか?
A

int.Parse()decimal.Parse() のオーバーロードに CultureInfo.InvariantCultureNumberStyles.AllowThousands を指定することで、カルチャに依存しない形式やカンマを許容する形式で解析できます。これにより、異なる地域設定での問題を回避できます。

Q
string.Format()FormatException が出た場合はどうすれば良いですか?
A

string.Format()FormatExceptionは、プレースホルダーのインデックスが引数の数を超えているか、フォーマット指定子が不正な場合に発生します。引数の数とプレースホルダーのインデックスを確認し、正しいフォーマット指定子を使用してください。

免責事項: 当記事の情報は執筆時点の内容に基づいています。最新情報は各公式サイトをご確認ください。当サイトは情報提供を目的としており、資格取得・技術的対応の結果について一切の責任を負いません。

コメント

デプロイ太郎のSNSを見てみる!!
タイトルとURLをコピーしました