How to Convert a String to an Int in C: Methods, Pitfalls, and When Each Approach Makes Sense
Converting a string to an integer is one of the most common tasks in C programming — and one of the most mishandled. Whether you're parsing user input, reading values from a file, or processing data from a network stream, understanding how each conversion method works (and where it can break) shapes the reliability of your entire program.
Why String-to-Integer Conversion Matters in C
Unlike higher-level languages that handle type coercion quietly in the background, C requires you to be explicit. A string like "42" and the integer 42 are fundamentally different data types in memory. One is a null-terminated array of characters; the other is a binary numeric value. Bridging that gap cleanly — without undefined behavior, data loss, or silent errors — is a skill that separates solid C code from fragile code.
The Main Methods for Converting a String to Int in C
1. atoi() — Simple but Risky
The atoi() function (from <stdlib.h>) is the most straightforward option:
#include <stdlib.h> int main() { const char *str = "123"; int num = atoi(str); return 0; } What it does: Parses the string from left to right, skipping leading whitespace, and converts digits until it hits a non-digit character.
The problem:atoi() has no error handling. If the string is "abc", it returns 0 — the same result as "0". You cannot tell the difference between a valid zero and a failed conversion. For throwaway scripts or internal tools where the input is controlled, this may be acceptable. For anything touching user input or external data, it's a liability.
2. strtol() — The Recommended Standard Approach
strtol() (also from <stdlib.h>) gives you everything atoi() doesn't:
#include <stdlib.h> #include <errno.h> int main() { const char *str = "456xyz"; char *endptr; errno = 0; long result = strtol(str, &endptr, 10); if (endptr == str) { // No digits were converted } else if (*endptr != ' ') { // Conversion stopped early — trailing non-numeric characters } else if (errno == ERANGE) { // Value out of range for long } return 0; } Key advantages:
- The
endptrpointer tells you exactly where parsing stopped errnoreports overflow or underflow viaERANGE- The
baseparameter supports any numeric base (binary, octal, hex, decimal)
One important detail: strtol() returns a long, not an int. If your target is int, you'll need to manually check that the result fits within INT_MIN and INT_MAX (defined in <limits.h>).
3. sscanf() — Flexible but Verbose
sscanf() from <stdio.h> can parse integers out of strings using format specifiers:
#include <stdio.h> int main() { const char *str = "789"; int num; if (sscanf(str, "%d", &num) == 1) { // Conversion succeeded } return 0; } sscanf() returns the number of items successfully matched. Checking that return value gives you basic error detection. It's particularly useful when your string contains mixed content and you need to extract an integer from a specific position or pattern.
The tradeoff: it's heavier than strtol() for pure integer parsing, and its error reporting is less granular around edge cases like overflow.
Factors That Determine Which Method to Use 🔧
| Factor | Best Fit |
|---|---|
| Controlled, trusted input | atoi() may be sufficient |
| User input or external data | strtol() with full error checking |
| Mixed-format strings | sscanf() |
| Need hex or octal parsing | strtol() with custom base |
| Embedded / resource-limited systems | Depends on library availability |
| Strict standards compliance (C99/C11) | strtol() or sscanf() |
Common Pitfalls to Know 💡
Overflow behavior: If the numeric value in the string exceeds the range of the target type, behavior differs by function. strtol() sets errno = ERANGE and returns LONG_MAX or LONG_MIN. atoi() produces undefined behavior.
Whitespace handling: All three methods skip leading whitespace, but they handle trailing whitespace differently. strtol() leaves endptr pointing at the first non-converted character, letting you inspect it.
Null pointer inputs: Passing a null pointer to any of these functions is undefined behavior. Always validate that your string pointer is non-null before calling conversion functions.
Locale sensitivity: In some environments, strtol() behavior can be influenced by locale settings, particularly with character classification. For portable code parsing plain decimal integers, this rarely causes issues — but it's worth knowing.
The int vs long distinction: On most 64-bit systems, long is 64 bits while int is 32 bits. A value like 3000000000 fits in a long but overflows an int. If you're using strtol() and storing into an int, the range check is your responsibility.
How Skill Level and Use Case Shape the Right Choice
A beginner writing a simple command-line calculator might reach for atoi() and never encounter a problem. A developer building a data ingestion pipeline that reads thousands of values from CSV files needs strtol() with explicit error handling at every conversion step — because one malformed value crashing silently could corrupt an entire dataset.
The compiler version and C standard you're targeting also matter. C99 and C11 both support strtol() and sscanf() consistently. Older codebases or embedded toolchains sometimes have partial standard library implementations where certain functions behave differently or aren't available.
The nature of the data itself adds another layer: parsing integers from a user-facing form field is a different risk profile than parsing integers out of a binary protocol's debug representation or reading configuration values from a trusted internal file.
Understanding the full spectrum — from atoi()'s simplicity to strtol()'s control — means the right choice in your situation depends on how much you trust the input, how you need to handle failures, and what your target environment looks like.