Question
I want to convert a string returned from flag.Arg(n) into an int in Go. What is the idiomatic way to do this?
For example, flag.Arg(n) returns a string, and I need to safely parse that value as an integer in a typical Go program.
Short Answer
By the end of this page, you will understand how to convert a string to an integer in Go using the standard library, especially strconv.Atoi. You will also learn how to handle invalid input, how parsing works step by step, and when to use related functions such as strconv.ParseInt.
Concept
In Go, values do not automatically change from one type to another. If you have a string like "42" and want an integer, you must parse the string.
The idiomatic way to convert a decimal string to an int is:
strconv.Atoi(s)
This function belongs to Go's strconv package. It reads a string and tries to interpret it as a base-10 integer.
Why this matters:
- Command-line arguments are often strings.
- Data from files, APIs, and environment variables usually arrives as text.
- Programs often need numeric values for calculations, limits, counts, or indexes.
In Go, parsing returns two values:
- the parsed integer
- an error
That error is important. If the input is not a valid integer, Go expects you to handle the failure explicitly.
Example:
n, err := strconv.Atoi("42")
nbecomes42errbecomesnil
If the string were "abc", parsing would fail and err would contain information about the problem.
This explicit error handling is a core part of writing reliable Go code.
Mental Model
Think of parsing like reading a number written on a note.
- A string is the note: it contains characters.
- An int is the actual numeric value your program can calculate with.
strconv.Atoiis the reader that checks whether the note really contains a valid whole number.
If the note says "123", the reader gives you the number 123.
If the note says "hello", the reader cannot turn that into a number, so it reports an error.
So the idea is:
- strings are text
- ints are numeric values
- parsing is the process of turning valid text into a number
Syntax and Examples
Basic syntax
value, err := strconv.Atoi(s)
smust be a stringvalueis the parsedinterrisnilif parsing succeeds
You need to import the package first:
import "strconv"
Example with flag.Arg
package main
import (
"flag"
"fmt"
"strconv"
)
func main() {
flag.Parse()
arg := flag.Arg(0)
if arg == "" {
fmt.Println("Please provide a number.")
return
}
n, err := strconv.Atoi(arg)
if err != nil {
fmt.Println("Invalid number:", err)
return
}
fmt.Println("Parsed integer:", n)
}
What this does
- Reads the first non-flag command-line argument
- Checks whether it exists
- Converts it from a string to an integer
- Prints an error if the input is invalid
Another simple example
s := "25"
n, err := strconv.Atoi(s)
if err != nil {
fmt.Println("Could not parse:", err)
return
}
fmt.Println(n + 5) // 30
Here, the string "25" becomes the integer 25, so arithmetic works as expected.
Step by Step Execution
Consider this code:
package main
import (
"fmt"
"strconv"
)
func main() {
s := "42"
n, err := strconv.Atoi(s)
if err != nil {
fmt.Println("parse failed")
return
}
fmt.Println(n)
}
Step-by-step
-
s := "42"- A string variable named
sis created. - Its value is the text
"42".
- A string variable named
-
n, err := strconv.Atoi(s)- Go calls
strconv.Atoiwiths. - The function reads the characters in
"42". - Since
"42"is a valid integer, it returns:n = 42err = nil
- Go calls
-
if err != nil- Go checks whether parsing failed.
- Since
errisnil, the condition is false. - The program continues.
-
fmt.Println(n)- Prints
42
- Prints
If the input were invalid
If you changed this line:
s := "forty-two"
Then strconv.Atoi(s) would return:
n = 0err != nil
The program would enter the if block and print parse failed.
That is why checking the error matters.
Real World Use Cases
String-to-integer conversion is very common in Go programs.
Command-line tools
Arguments from flag.Arg() are strings. You often parse them into numbers for:
- port numbers
- retry counts
- time limits
- item IDs
Environment variables
Configuration values often come from environment variables as strings:
portStr := os.Getenv("APP_PORT")
port, err := strconv.Atoi(portStr)
Reading files
A file may contain numeric text such as:
- user ages
- scores
- quantities
- record IDs
API and form input
Even when a value represents a number, it may arrive as a string in:
- JSON fields stored as strings
- URL query parameters
- form submissions
Data processing
CSV and text-based formats often store numbers as text. Parsing is required before calculations, sorting, or validation.
Real Codebase Usage
In real Go codebases, developers usually combine strconv.Atoi with validation and clear error handling.
Common pattern: parse and validate
count, err := strconv.Atoi(flag.Arg(0))
if err != nil {
return fmt.Errorf("count must be an integer: %w", err)
}
if count < 0 {
return fmt.Errorf("count must be non-negative")
}
This pattern is common because parsing alone does not guarantee the value is meaningful.
Guard clause style
Go code often exits early when input is invalid:
arg := flag.Arg(0)
if arg == "" {
return
}
n, err := strconv.Atoi(arg)
if err != nil {
return
}
This keeps the code simple and readable.
Wrapping errors
In larger projects, developers often wrap parsing errors with context:
n, err := strconv.Atoi(input)
if err != nil {
return fmt.Errorf("invalid user id %q: %w", input, err)
}
This makes logs and debugging much more useful.
Parsing configuration
Apps often parse config values during startup and fail fast if invalid.
Using ParseInt when more control is needed
If a project needs a specific bit size or base, developers use strconv.ParseInt instead of Atoi.
Common Mistakes
1. Forgetting to import strconv
Broken code:
n, err := Atoi("123")
Why it fails:
Atoiis not in the current package.- You must import
strconvand callstrconv.Atoi.
Correct version:
import "strconv"
n, err := strconv.Atoi("123")
2. Ignoring the error
Broken code:
n, _ := strconv.Atoi("abc")
fmt.Println(n)
Why it is a problem:
- Invalid input returns an error.
- If you ignore it,
nmay be0, which can hide bugs.
Better version:
n, err := strconv.Atoi("abc")
if err != nil {
fmt.Println("invalid integer")
return
}
3. Assuming an empty string is valid
Broken code:
arg := flag.Arg(0)
n, err := strconv.Atoi(arg)
Why it can fail:
- If no argument was provided,
flag.Arg(0)may be"". - An empty string is not a valid integer.
Better version:
arg := flag.Arg(0)
if arg == "" {
fmt.Println("missing number")
return
}
4. Trying to use a type conversion instead of parsing
Broken code:
s := "123"
// int(s) is not string-to-number parsing
Why it is wrong:
- Type conversion and parsing are different.
int(s)does not mean “read this string as a number.”
Use:
n, err := strconv.Atoi(s)
5. Using parsed values without validation
Even valid integers may still be unacceptable.
Example:
age, err := strconv.Atoi(input)
if err != nil {
return err
}
if age < 0 {
return fmt.Errorf("age cannot be negative")
}
Parsing checks format. Validation checks meaning.
Comparisons
strconv.Atoi vs strconv.ParseInt
| Function | Returns | Best for | Notes |
|---|---|---|---|
strconv.Atoi(s) | int, error | Simple decimal string to int conversion | Most idiomatic for common cases |
strconv.ParseInt(s, base, bitSize) | int64, error | More control over base and size | Useful for binary, hex, or specific integer sizes |
Example
n, err := strconv.Atoi("42")
vs.
n64, err := strconv.ParseInt("42", 10, 64)
Parsing vs type conversion
| Operation | Purpose | Example |
|---|---|---|
| Parsing | Convert text into a numeric meaning | strconv.Atoi("42") |
| Type conversion | Convert between compatible Go types | int(myInt64) |
Atoi vs Sscanf
| Approach | Best for | Recommendation |
|---|---|---|
strconv.Atoi | Simple integer parsing | Preferred for plain numeric strings |
fmt.Sscanf | Structured formatted input | Usually unnecessary for a single integer |
For a single integer string, strconv.Atoi is clearer and more idiomatic.
Cheat Sheet
Quick reference
import "strconv"
n, err := strconv.Atoi(s)
What it does
- Converts a base-10 string to
int - Returns
(int, error)
Common pattern
n, err := strconv.Atoi(input)
if err != nil {
// handle invalid input
}
With flag.Arg
arg := flag.Arg(0)
n, err := strconv.Atoi(arg)
if err != nil {
// handle error
}
Valid examples
"0"
"42"
"-7"
Invalid examples
""
"abc"
"12.5"
"7px"
When to use ParseInt
Use this when you need:
- a specific base
- a specific bit size
- an
int64result
n, err := strconv.ParseInt("ff", 16, 64)
Key rule
Always check err before using the parsed value.
FAQ
How do I convert a string to an int in Go?
Use strconv.Atoi:
n, err := strconv.Atoi(s)
What is the idiomatic way to parse flag.Arg(n) as an integer in Go?
Read the argument as a string, then call strconv.Atoi, and handle the error.
What happens if the string is not a valid integer?
strconv.Atoi returns an error. You should check err before using the result.
Can strconv.Atoi parse negative numbers?
Yes. For example, "-10" parses successfully.
Can strconv.Atoi parse floating-point values like "3.14"?
No. It only parses integer strings. Use strconv.ParseFloat for floating-point numbers.
Should I use Atoi or ParseInt?
Use Atoi for normal decimal string-to-int conversion. Use ParseInt when you need more control over base or bit size.
Why can't I use int(myString)?
Because that is not string parsing. In Go, converting a string to an integer value requires parsing with strconv.
Mini Project
Description
Build a small command-line program that reads a number from the command line and reports whether it is valid, even, or odd. This demonstrates the common real-world flow of reading string input, converting it to an integer, handling errors, and then using the numeric value in logic.
Goal
Create a Go program that safely parses a command-line argument into an integer and performs simple numeric checks.
Requirements
- Read the first non-flag command-line argument.
- Show a helpful message if no argument is provided.
- Convert the argument from string to integer.
- Show an error message if the value is not a valid integer.
- Print whether the number is even or odd.
Keep learning
Related questions
Are Go Maps Passed by Value or Reference?
Learn Go map parameter and return semantics: maps are passed by value, while copies share underlying data. Know when map pointers are useful.
Authentication for Go REST APIs: Sessions, Tokens, and Middleware
Learn practical authentication patterns for Go REST APIs, including password hashing, server sessions, bearer tokens, middleware, and security rules.
Automatic Build Versioning in Go: Embed Incrementing Build Numbers
Learn how to add automatic build versioning in Go using linker flags, build metadata, CI counters, and Git-based version values.