Question

printf Long Format Specifier in C

cprintflong-integer

Question

In C, printf uses conversion specifiers such as %d or %i to print a signed int. What conversion specifier should be used to print a long value correctly?

Short Answer

By the end of this page, you will understand how printf formats long values in C, why the correct conversion specifier matters, how length modifiers work, and how to avoid common type-mismatch bugs when printing integers.

Concept

printf in C does not guess argument types at runtime. It relies entirely on the format string you provide.

For integer output, the base conversion specifier for a signed decimal integer is %d or %i. To print other integer types, C uses length modifiers that are placed before the conversion letter.

For a long, the correct signed decimal format is:

%ld

You can also use:

%li

Both are valid for printf when printing a signed long, though %ld is more commonly used.

For an unsigned long, use:

%lu

This matters because printf is a variadic function. Variadic functions do not know the actual types of extra arguments unless the format string describes them correctly. If you pass a long but use %d, printf will interpret the bytes as if they were an int, which can produce incorrect output and causes undefined behavior.

In real programs, this becomes especially important when:

  • printing counters n- working with file sizes or timestamps
  • logging numeric values
  • handling platform-dependent integer sizes

Using the correct format keeps your output accurate and your code portable.

Mental Model

Think of printf like a labeling machine in a warehouse.

  • The value is the package.
  • The format specifier is the label telling the machine what kind of package it is.

If you put a long package on the belt but label it as %d (an int), the machine reads it using the wrong instructions. Sometimes the output looks almost right, sometimes it is completely wrong, and sometimes it causes subtle bugs.

%ld means: “This is a signed decimal number, and its type is long.”

Take Quiz

Syntax and Examples

The general syntax is:

printf("format string", value);

For long, use %ld:

#include <stdio.h>

int main(void) {
    long distance = 1234567890L;
    printf("Distance: %ld\n", distance);
    return 0;
}

Output:

Distance: 1234567890

For unsigned long, use %lu:

#include <stdio.h>

int main(void) {
    unsigned long population = 4000000000UL;
    printf("Population: %lu\n", population);
    return 0;
}

For other common integer types:

int a = 10;
long b = 20L;
long long c = 30LL;

printf("int: %d\n", a);
printf("long: %ld\n", b);
printf("long long: %lld\n", c);

A broken example:

long value = 1234567890L;
printf("%d\n", value);   // Wrong

Correct version:

printf("%ld\n", value); // Correct

Even if the wrong version appears to work on one machine, it is still incorrect C.

Step by Step Execution

Consider this example:

#include <stdio.h>

int main(void) {
    long score = 500000L;
    printf("Score = %ld\n", score);
    return 0;
}

Step by step:

  1. long score = 500000L;

    • A variable named score is created.
    • Its type is long.
    • The L suffix makes the literal a long constant.
  2. printf("Score = %ld\n", score);

    • printf reads the format string.
    • It finds %ld.
    • %l means the argument is a long.
    • d means print it as a signed decimal integer.
    • printf reads score as a long and prints 500000.
  3. \n

    • Moves output to the next line.
  4. return 0;

    • Ends the program successfully.

If the code had used %d instead of %ld, printf would expect an int, not a long. That mismatch leads to undefined behavior.

Real World Use Cases

Printing long values appears in many practical situations:

  • Counters and IDs

    • Large loop counters
    • Record IDs stored in long
  • Timestamps

    • Unix-style time values are often stored in larger integer types
  • File sizes and offsets

    • Programs may use long or related integer types for file positions
  • System logs

    • Logging process data, durations, counts, or totals
  • Scientific and numeric programs

    • Intermediate results may exceed the range of int

Example:

long total_requests = 1250000L;
printf("Processed requests: %ld\n", total_requests);

In each case, the format string must match the actual variable type.

Take Quiz

Real Codebase Usage

In real codebases, developers usually combine correct format specifiers with a few common patterns:

Validation and logging

if (count < 0) {
    printf("Invalid count: %ld\n", count);
    return 1;
}

This is a simple example of a guard clause: detect a bad value early, log it, and stop.

Debug output

long retries = 3L;
printf("Retry attempt: %ld\n", retries);

Developers often print numeric state while debugging.

Configuration values

long timeout_ms = 5000L;
printf("Timeout set to %ld ms\n", timeout_ms);

Configuration values are often read, validated, and then logged.

Matching type and format consistently

Teams usually try to keep these aligned:

  • variable type: long
  • literal suffix: L when useful
  • format string: %ld

That consistency makes code easier to review and less error-prone.

Compiler warnings as protection

Real projects often compile with warnings enabled, such as:

gcc -Wall -Wextra -Wformat program.c

These warnings help catch mistakes like using %d for a long.

Common Mistakes

1. Using %d for a long

Broken code:

long n = 100000L;
printf("%d\n", n);

Problem:

  • %d expects an int
  • n is a long
  • This is undefined behavior

Fix:

printf("%ld\n", n);

2. Forgetting unsigned types need different specifiers

Broken code:

unsigned long n = 42UL;
printf("%ld\n", n);

Problem:

  • %ld is for signed long
  • n is unsigned long

Fix:

printf("%lu\n", n);

3. Confusing long with long long

Broken code:

long long big = 9000000000LL;
printf("%ld\n", big);

Fix:

printf("%lld\n", big);

4. Assuming sizes are the same on every platform

Some systems have:

  • int = 32 bits
  • long = 32 bits

Others may have:

  • int = 32 bits
  • long = 64 bits

Do not assume %d is “close enough.” Always match the actual type.

5. Ignoring compiler warnings

If the compiler says the format does not match the argument type, take it seriously. These warnings often catch real bugs early.

Comparisons

Here is a quick comparison of common integer format specifiers in C:

TypeSigned formatUnsigned formatExample variable
int%d or %i%uint x = 10;
long%ld or %li%lulong x = 10L;
long long%lld%llulong long x = 10LL;
short%hd%hushort x = 10;

%d vs %i

For printf, %d and %i behave the same for output.

%ld vs %li

For printf, both print a signed long.

%ld vs %lld

  • %ld is for long
  • %lld is for long long

Choose the one that matches your variable exactly.

Take Quiz

Cheat Sheet

  • Print signed long: %ld
  • Print unsigned long: %lu
  • Print signed int: %d or %i
  • Print signed long long: %lld

Examples:

long a = 123L;
unsigned long b = 123UL;
long long c = 123LL;

printf("%ld\n", a);
printf("%lu\n", b);
printf("%lld\n", c);

Rules:

  • l is the length modifier for long
  • d and i are signed decimal output specifiers
  • The format string must match the argument type exactly
  • Mismatched types in printf cause undefined behavior

Useful reminders:

  • %ld = signed long
  • %lu = unsigned long
  • %li also works for signed long in printf
  • Enable compiler warnings to catch mistakes

Compilation tip:

gcc -Wall -Wextra -Wformat program.c

FAQ

What is the correct printf specifier for a long in C?

Use %ld for a signed long.

Can I use %i for a long?

Not by itself. For a long, use %li or %ld. In printf, both are valid for signed decimal output.

What is the specifier for unsigned long?

Use %lu.

Why is %d wrong for a long?

Because %d expects an int. If you pass a long, the format and argument types do not match, which causes undefined behavior.

Is %ld the same as %li?

For printf, yes. Both print a signed long as decimal output.

What about long long?

Use %lld for signed long long and %llu for unsigned long long.

Will the wrong format always fail visibly?

No. Sometimes it may appear to work, but the code is still incorrect and non-portable.

Take Quiz

Mini Project

Description

Build a small C program that prints several integer variables using the correct printf format specifiers. This reinforces how signed and unsigned integer types must match their format strings exactly.

Goal

Create a program that correctly prints int, long, unsigned long, and long long values.

Requirements

  1. Declare one variable of type int.
  2. Declare one variable of type long.
  3. Declare one variable of type unsigned long.
  4. Declare one variable of type long long.
  5. Print each variable using the correct printf conversion specifier.
Take Quiz

Keep learning

Related questions

View more