/commands/rust/parse-string-to-int
rust convert string to int with parse::<i32>()
- tool
- Rust
- versions
- Rust 1.0+, IntErrorKind: Rust 1.55+
- os
- any
"42".parse::<i32>() converts a string to an integer and returns a Result<i32, ParseIntError>: Ok(42) on success, Err for empty strings, invalid characters or values outside the type's range. Handle the Result with ?, match, unwrap_or or if let; call .trim() first when the text comes from user input or a file.
Success and failure cases
cat > parse.rs <<'EOF'
use std::num::ParseIntError;
fn total(items: &[&str]) -> Result<i64, ParseIntError> {
let mut sum = 0;
for s in items {
sum += s.trim().parse::<i64>()?; // ? returns the first error
}
Ok(sum)
}
fn main() {
for input in ["42", "-7", " 8 ", "+5", "3.5", "", "abc", "300"] {
match input.parse::<u8>() {
Ok(n) => println!("{:>7} -> Ok({n})", format!("{input:?}")),
Err(e) => println!("{:>7} -> Err({:?}): {e}", format!("{input:?}"), e.kind()),
}
}
let port: u16 = "8080".parse().unwrap_or(80);
println!("port = {port}");
println!("hex ff = {:?}", i32::from_str_radix("ff", 16));
println!("total = {:?}", total(&["1", " 2", "3 "]));
println!("total = {:?}", total(&["1", "two"]));
}
EOF
rustc --edition 2024 parse.rs && ./parseOutput
"42" -> Ok(42)
"-7" -> Err(InvalidDigit): invalid digit found in string
" 8 " -> Err(InvalidDigit): invalid digit found in string
"+5" -> Ok(5)
"3.5" -> Err(InvalidDigit): invalid digit found in string
"" -> Err(Empty): cannot parse integer from empty string
"abc" -> Err(InvalidDigit): invalid digit found in string
"300" -> Err(PosOverflow): number too large to fit in target type
port = 8080
hex ff = Ok(255)
total = Ok(6)
total = Err(ParseIntError { kind: InvalidDigit })Parsing to u8 shows every failure kind: whitespace is not ignored (" 8 " fails until trimmed), a leading + is accepted, -7 is an invalid digit because an unsigned type has no sign, 3.5 is not an integer, and 300 overflows u8. The IntErrorKind from e.kind() lets you react to each case separately.
Common patterns
| Code | Behaviour |
|---|---|
| let n: i32 = s.parse()?; | Propagate the error to the caller (function returns Result) |
| s.parse::<i32>().unwrap_or(0) | Fall back to a default value |
| s.trim().parse::<i32>() | Ignore surrounding spaces and the newline from read_line |
| s.parse::<i32>().ok() | Convert to Option<i32>, discarding the error |
| i64::from_str_radix("ff", 16) | Parse in another base (2 to 36), no 0x prefix allowed |
| s.parse::<f64>() | Floating-point numbers such as 3.5 or 1e3 |
| s.parse::<u64>().expect("not a number") | Panic with a message: fine in examples, avoid for user input |
Pitfalls
- Type inference errors.
let n = s.parse().unwrap();fails to compile with E0284 ("type annotations needed") because rustc cannot know the target type. Add::<i32>or a type on the variable. - Mixing types. Assigning the parsed
i64to ani32field fails with E0308 mismatched types; parse directly into the type you need or convert withi32::try_from(n). - Thousand separators and prefixes (
1,000,0x1F,1_000) are not accepted byparse; strip them, or usefrom_str_radixfor other bases. - Unwrapping user input panics with
called Result::unwrap() on an Err value: ParseIntError { kind: InvalidDigit }. Match on the result instead.
Confirm it worked
Print the Result with {:?} as in the example: Ok(n) means the conversion succeeded. Testing "", a value out of range and one with spaces catches the cases real input will contain.
FAQ
Why does parse fail on "42\n" read from stdin?
read_line keeps the newline, and parse does not ignore whitespace. Call .trim() first: input.trim().parse::<i32>().
How do I parse a number with a decimal point?
Use a float type: "3.5".parse::<f64>(). Parsing it as an integer type fails with an invalid digit error, and converting a float to an integer afterwards with as truncates toward zero.
Can I write parse() without the ::<i32> turbofish?
Yes, when the target type is known from context, for example let n: i32 = s.parse()?; or when the value is passed to a function that takes an i32.