When a C or C++ library call fails, it often sets the global variable errno to a numeric error code. The strerror() function turns that number into a plain-English message like No such file or directory—so users and developers understand what went wrong without memorizing error constants.
01
errno Codes
System errors.
02
Readable Text
Human messages.
03
char* Return
Library string.
04
vs perror()
Return vs print.
05
File I/O
fopen failures.
06
<cerrno>
ENOENT, EINVAL.
Fundamentals
Definition and Usage
In C++, strerror() is declared in <cstring>. You pass an integer error code—usually the value of errno immediately after a failed system call—and receive a pointer to a short descriptive C-string managed by the C library.
This function does not clear or modify errno. It only translates a number you supply. Messages are defined by the operating system and may vary slightly between platforms, but common codes like ENOENT and EACCES produce familiar text on most systems.
💡
Beginner Tip
Save errno to a local variable right after a failure: int err = errno; then call strerror(err). Other functions (including strerror itself on some platforms) may change errno before you read it again.
Foundation
📝 Syntax
Function signature and required headers:
C++
#include <cstring>
#include <cerrno>
char* strerror(int errnum);
// Typical usage after a failed call:
// int err = errno;
// const char* msg = strerror(err);
Parameters
errnum — an error number, commonly errno or a constant like ENOENT.
Return Value
Returns a pointer to a null-terminated message string. The storage is owned by the library—copy it if you need to keep the text beyond the next call to strerror().
Cheat Sheet
⚡ Quick Reference
Constant
Typical meaning
Example scenario
ENOENT
No such file or directory
Missing file path
EACCES
Permission denied
Read protected file
EINVAL
Invalid argument
Bad function parameter
ENOMEM
Out of memory
Allocation failed
Translate
strerror(errno)
Current error
Save first
int e = errno;
Before other calls
Copy
std::string msg
Keep message safe
Print fast
perror("open")
stderr helper
Hands-On
Examples Gallery
Compile with g++ strerror.cpp -std=c++17 -o strerror. These examples show how to turn numeric error codes into messages beginners can read and log.
📚 Getting Started
Translate a known error constant into readable text.
Example 1 — Basic strerror() with ENOENT
Simulate a “file not found” error and print the corresponding message.
Constructing a std::string copies the C-string immediately. The copy survives later calls to strerror and is easier to pass around in modern C++ code.
Applications
🚀 Common Use Cases
File and I/O errors — explain why fopen, read, or write failed.
User-facing error dialogs — show a readable reason instead of a raw number.
Logging and diagnostics — include system messages in log files.
Teaching and debugging — learn what constants like ENOENT mean in practice.
Wrapper functions — convert low-level failures into std::string exceptions or error types.
🧠 How strerror() Works
1
System call fails
A library function sets errno to a numeric code.
errno
2
Save the code
Copy errno to a local variable before other calls.
Capture
3
Lookup message
strerror(errnum) maps the number to a predefined text table.
Lookup
💬
📝
Return C-string
Pointer to text such as “Permission denied”—copy it if you need it later.
Important
📝 Notes
Include <cerrno> for errno and symbolic constants; include <cstring> for strerror.
The returned pointer must not be freed with delete or free.
Read errno immediately after failure—successful calls may leave it unchanged from an older error.
C++ exceptions (std::system_error) are the modern alternative for new code, but errno + strerror remains common in C APIs.
Error text may be translated according to system locale settings.
Performance
⚡ Optimization
strerror() is fast enough for error paths that run rarely. Avoid calling it inside tight loops on success paths. Cache the copied message once per failure instead of translating the same code repeatedly. For hot paths, log the numeric errno and translate offline if needed.
Wrap Up
Conclusion
strerror() bridges the gap between numeric system errors and messages humans can understand. Save errno promptly, pass it to strerror, and copy the result when you need to keep or share the text.
Next, learn strlen() to measure C-string length—a building block for safe buffer sizing before calls like strcpy.
Copy the message into std::string for logs or returns
Check return values (nullptr, -1) before reading errno
Use meaningful context: "Config load failed: " + msg
Learn common codes: ENOENT, EACCES, EINVAL
❌ Don’t
Free or modify the pointer returned by strerror
Assume errno is zero on success for all functions
Call strerror twice and compare pointers expecting different strings
Rely on strerror in multi-threaded code without copying the text
Show raw errno numbers to end users without translation
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about strerror()
Use these points whenever system calls fail in your programs.
5
Core concepts
💬01
errno → Text
Decode errors.
Basics
📝02
char* Return
Library owned.
Return
💾03
Save errno
Before other calls.
Safety
🚫04
vs perror
String vs print.
Compare
📁05
File I/O
fopen failures.
Use case
❓ Frequently Asked Questions
strerror() takes an integer error code (such as the value stored in errno) and returns a pointer to a human-readable description of that error, for example "No such file or directory" for ENOENT.
Include <cstring> for strerror() and <cerrno> for errno and symbolic constants like ENOENT and EINVAL. Some programs also include <iostream> for output.
Pass the error number: strerror(errno). Many system calls set errno when they fail; read errno immediately after the failing call, then pass it to strerror() before other library calls overwrite errno.
strerror() returns a message string you can store, log, or format. perror() prints a message directly to stderr, prefixed with your custom text. Use strerror() when you need the text in your own output; use perror() for quick console diagnostics.
No. The pointer refers to static storage managed by the C library. Do not call delete or free on it. Copy the text to a std::string if you need to keep it across later calls to strerror().
Classic strerror() may use a shared static buffer on some platforms, so concurrent calls can overwrite each other's text. For multi-threaded code, copy the result immediately into a std::string, or use platform-specific alternatives like strerror_r (POSIX) or strerror_s when available.
Did you know?
On POSIX systems, errno is a macro that expands to a thread-local integer. Each thread has its own error code, but the string returned by classic strerror() may still share static storage—copy the message if multiple threads format errors at the same time.