← Debugging Guides

阅读中文版本

C# FormatException: input string was not in a correct format

Fix C# FormatException from Parse and string.Format by using TryParse, culture-aware parsing, and escaping literal braces.

beginnerdebuggingcsharpparsinglocalization

Symptoms

  • System.FormatException: Input string was not in a correct format
  • int.Parse fails on a value with spaces or a currency symbol
  • string.Format throws when the template contains a literal brace

Possible causes

  • int.Parse/double.Parse on a non-numeric or empty string
  • Parsing with the wrong culture (comma vs dot decimal separator)
  • string.Format with an unescaped literal { or }
  • Composite formatting index out of range

Diagnosis steps

Print the exact input string

Console.WriteLine($"[{input}]");

Interpretation

Brackets reveal hidden whitespace and empty strings that cause the parse to fail.

Switch to TryParse to distinguish formats

int.TryParse(input, out var n)

Interpretation

A false return confirms the format, not the value range, is the problem.

Check culture and format specifiers

Interpretation

A decimal comma parsed under the invariant culture, or vice versa, throws FormatException.

Root cause

FormatException means the string was syntactically unacceptable for the operation. Parse requires the entire string (minus allowed whitespace) to match a number with the current culture; string.Format requires literal braces to be doubled. Neither operation coerces a malformed value silently.

Fix

Use TryParse for untrusted input and supply an explicit CultureInfo where formats vary. Escape literal braces in composite format strings as {{ and }}. Validate and normalise input (trim, strip separators) before parsing, and prefer DateTime.ParseExact with a format string for dates.

Verify the fix

Re-run with the previously failing string; TryParse returns the expected value, and a test asserts the malformed input yields a clear validation error rather than an unhandled FormatException.

Symptoms

Operations throw FormatException: Input string was not in a correct format. It often appears with real user input while hard-coded values parse fine.

Diagnosis

Print the exact string and try a safe parse:

Console.WriteLine($"[{input}]");        // exposes spaces / empty
if (!int.TryParse(input, out var n)) {
    Console.WriteLine("not a number");
}

Check culture for decimal separators.

Fix

Use TryParse and explicit cultures; escape braces:

int.TryParse(input.Trim(), NumberStyles.Integer, CultureInfo.InvariantCulture, out var n);

var json = string.Format(CultureInfo.InvariantCulture, "{{ \"n\": {0} }}", n);

Verification

Re-run with the offending string; the value parses or is rejected cleanly. A test asserts the malformed input produces a validation error instead of an unhandled FormatException.

Culture Is Part of the Contract

A number like 1,5 is fifteen to some cultures and invalid to others, so parsing without an explicit culture borrows the machine’s setting and makes behaviour depend on locale. Always pass CultureInfo.InvariantCulture for machine formats such as config keys and wire data, and the user’s culture only for display. The same discipline applies to dates: DateTime.ParseExact with an explicit pattern rejects surprising input that DateTime.Parse would guess at. Centralising these helpers removes a whole class of environment-specific failures that only reproduce on certain machines.