Skip to content
C Basics: Validate an Entire Decimal Number with strtol

C Basics: Validate an Entire Decimal Number with strtol

November 1, 2026

A conversion that accepts the beginning of a string is not complete validation. Parse a decimal port while deliberately rejecting whitespace, signs, suffixes, overflow, and out-of-range values.

Prepare a scratch directory

Tested on Linux x86-64 with GCC 14.2.0. You need GCC, the C development headers, Bash, a text editor, and the standard mktemp, rm, and rmdir utilities. This example uses the C standard library and no external package.

Keep the same terminal open. Stop if setup fails, before saving the source:

start_directory="$PWD"
work_directory="$(mktemp -d)" || exit 1
cd -- "$work_directory" || exit 1

Run the example

Save this as strtol-validation-demo.c:

#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

static bool parse_port(const char *text, long *port) {
    if (*text < '0' || *text > '9') {
        return false;
    }
    char *end;
    errno = 0;
    long parsed = strtol(text, &end, 10);
    if (end == text || *end != '\0' || errno == ERANGE ||
        parsed < 1 || parsed > 65535) {
        return false;
    }
    *port = parsed;
    return true;
}

int main(void) {
    const char *inputs[] = {
        "8080", "0", "70000", "80x", "", " 80", "+80",
        "9999999999999999999999999999999999999999"
    };
    for (size_t index = 0; index < sizeof inputs / sizeof inputs[0]; ++index) {
        long port = 0;
        if (parse_port(inputs[index], &port)) {
            printf("Accepted: %s -> %ld\n", inputs[index], port);
        } else {
            printf("Rejected: [%s]\n", inputs[index]);
        }
    }
    return EXIT_SUCCESS;
}

Compile and run it. The && prevents running an old executable if compilation fails:

gcc -std=c17 -Wall -Wextra -Werror -pedantic strtol-validation-demo.c -o strtol-validation-demo &&
./strtol-validation-demo

Observed output:

Accepted: 8080 -> 8080
Rejected: [0]
Rejected: [70000]
Rejected: [80x]
Rejected: []
Rejected: [ 80]
Rejected: [+80]
Rejected: [9999999999999999999999999999999999999999]

Read the result

The first-character check enforces the example’s digits-only policy. strtol uses base 10, returns the stopping position, and reports range overflow through errno. Clear errno before calling it; testing only the numeric result cannot distinguish every failure from a valid value.

Apply it carefully

The caller must supply a non-null, null-terminated string and a writable output pointer. This example starts in the standard C locale and never changes it. Leading zeroes are accepted as decimal. Parsing a port number does not prove that it is available or permitted to bind; those are separate runtime checks.

The library reference describes the relevant behavior.

Clean up

Remove only the source and executable created here, then remove the empty scratch directory:

rm -- strtol-validation-demo.c strtol-validation-demo
cd -- "$start_directory" || exit 1
rmdir -- "$work_directory"
unset start_directory work_directory

If the directory is not empty, inspect what remains before removing anything else.

Acknowledgements

This post was created with assistance from AI.

Last updated on