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:
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.”
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);
;
}
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:
-
long score = 500000L;- A variable named
scoreis created. - Its type is
long. - The
Lsuffix makes the literal alongconstant.
- A variable named
-
printf("Score = %ld\n", score);printfreads the format string.- It finds
%ld. %lmeans the argument is along.dmeans print it as a signed decimal integer.
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
longor related integer types for file positions
- Programs may use
-
System logs
- Logging process data, durations, counts, or totals
-
Scientific and numeric programs
- Intermediate results may exceed the range of
int
- Intermediate results may exceed the range of
Example:
long total_requests = 1250000L;
printf("Processed requests: %ld\n", total_requests);
In each case, the format string must match the actual variable type.
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:
Lwhen useful - format string:
%ld
Common Mistakes
1. Using %d for a long
Broken code:
long n = 100000L;
printf("%d\n", n);
Problem:
%dexpects anintnis along- 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:
%ldis for signedlongnis
Comparisons
Here is a quick comparison of common integer format specifiers in C:
| Type | Signed format | Unsigned format | Example variable |
|---|---|---|---|
int | %d or %i | %u | int x = 10; |
long | %ld or %li | %lu | long x = 10L; |
long long | %lld |
Cheat Sheet
- Print signed
long:%ld - Print unsigned
long:%lu - Print signed
int:%dor%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:
lis the length modifier forlongdandiare signed decimal output specifiers- The format string must match the argument type exactly
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?
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
- Declare one variable of type
int. - Declare one variable of type
long. - Declare one variable of type
unsigned long. - Declare one variable of type
long long. - Print each variable using the correct
printfconversion specifier.
Keep learning
Related questions
Building More Fault-Tolerant Embedded C++ Applications for Radiation-Prone ARM Systems
Learn practical C++ and compile-time techniques to reduce soft-error damage in embedded ARM systems exposed to radiation.
C printf Format Specifier for bool: How to Print Boolean Values
Learn how to print bool values in C with printf, why no %b/%B specifier exists, and the common patterns to print true/false or 0/1.
Calling C or C++ from Python: Building Python Bindings
Learn the quickest ways to call C or C++ from Python, including ctypes, C extensions, Cython, and binding tools with practical examples.