Understanding std::strtoumax for String-to-Unsigned Integer Conversion in C++
What it does
- It interprets the characters in the string according to a specified base (radix).
std::strtoumax
is a function in the C++ standard library (<cinttypes>
) that converts a string representation of a number to an unsigned integer of the maximum width (uintmax_t
).
Syntax
uintmax_t std::strtoumax(const char* str, char** endptr, int base);
Parameters
base
(optional): The base (radix) in which the string is represented. If not provided, it defaults to 10 (decimal). Valid bases are from 2 to 36.endptr
(optional): A pointer to a character pointer. Upon successful conversion,endptr
will point to the first character in the string that was not part of the valid number representation. Ifendptr
isnullptr
, it's ignored.str
: A null-terminated character array containing the string to be converted.
Return value
- If an error occurs (e.g., invalid characters, out-of-range value), it returns zero (
0
) and setserrno
to indicate the specific error. - If the conversion is successful, it returns the converted unsigned integer value.
Key points
- If the string is empty or contains only non-numeric characters,
std::strtoumax
returns zero and setserrno
toEINVAL
(invalid argument). - Leading whitespace (spaces, tabs, newlines) is skipped before conversion begins.
- Valid digits depend on the base:
- For bases 2 to 10, digits are
0
to9
. - For bases 11 to 36, digits include
0
to9
and uppercase or lowercase letters fromA
toZ
(depending on the implementation).
- For bases 2 to 10, digits are
- The string can optionally start with a plus (
+
) or minus (-
) sign, butstd::strtoumax
only handles unsigned integers, so the sign is ignored.
Example
#include <iostream>
#include <cinttypes>
int main() {
char str[] = "1234";
uintmax_t value;
char* endptr;
value = std::strtoumax(str, &endptr, 10); // Convert to decimal (base 10)
if (value != 0) {
std::cout << "Converted value (decimal): " << value << std::endl;
std::cout << "Character after parsed number: " << *endptr << std::endl;
} else {
std::cerr << "Error: Conversion failed." << std::endl;
}
return 0;
}
This code will output:
Converted value (decimal): 1234
Character after parsed number:
- Consider using a wrapper function that throws an exception (
std::invalid_argument
) on error for better error handling practices. - Always check the return value and
errno
to ensure successful conversion.
Converting a hexadecimal string
#include <iostream>
#include <cinttypes>
int main() {
char str[] = "FF0A";
uintmax_t value;
char* endptr;
value = std::strtoumax(str, &endptr, 16); // Convert to hexadecimal (base 16)
if (value != 0) {
std::cout << "Converted value (hexadecimal): 0x" << std::hex << value << std::endl;
std::cout << "Character after parsed number: " << *endptr << std::endl;
} else {
std::cerr << "Error: Conversion failed (invalid hexadecimal string)." << std::endl;
}
return 0;
}
This code converts the string "FF0A" (hexadecimal for 65226) and prints the result in both decimal and hexadecimal format.
Handling conversion errors
#include <iostream>
#include <cinttypes>
#include <cerrno>
int main() {
char str1[] = "1234";
char str2[] = "invalid_string";
uintmax_t value;
char* endptr;
// Successful conversion
value = std::strtoumax(str1, &endptr, 10);
if (value != 0) {
std::cout << "Converted value (decimal): " << value << std::endl;
}
// Error handling (invalid string)
value = std::strtoumax(str2, &endptr, 10);
if (value == 0 && errno == EINVAL) {
std::cerr << "Error: Invalid string for conversion." << std::endl;
} else {
std::cerr << "Unexpected error during conversion." << std::endl;
}
return 0;
}
This code demonstrates how to check for specific errors using errno
. It shows successful conversion and then handles the case where the string "invalid_string" cannot be converted to a number.
#include <iostream>
#include <cinttypes>
int main() {
char str[] = "4294967295"; // Maximum value for a 32-bit unsigned integer
uintmax_t value;
value = std::strtoumax(str, nullptr, 10); // Ignore endptr
if (value != 0) {
std::cout << "Converted value (decimal): " << value << std::endl;
} else {
std::cerr << "Error: Conversion failed (potentially out-of-range value)." << std::endl;
}
return 0;
}
std::stoul (C++11 and later)
- Syntax:
unsigned int value = std::stoul(str, &endptr, base);
- It offers similar functionality to
std::strtoumax
but provides more type flexibility. - Introduced in C++11,
std::stoul
is a more generic function that can convert strings to various unsigned integer types (unsigned int
,unsigned long
, etc.) based on the size of the result.
Custom string parsing
- This involves iterating through the string, checking each character for validity based on the desired base, and accumulating the result into the desired unsigned integer type.
- If you need more control over the conversion process or have specific validation requirements, you can write your own string parsing function.
Third-party libraries
- For complex parsing requirements or custom validation, a custom parsing function or a third-party library might be more suitable.
- For basic conversion with flexibility in result type,
std::stoul
is a good choice.
Alternative | Description | Advantages | Disadvantages |
---|---|---|---|
std::stoul (C++11+) | More generic conversion to various unsigned types | Type flexibility, simpler to use than custom parsing | Less control over parsing process compared to custom |
Custom parsing | User-defined logic for string parsing | Highly customizable, can perform specific validation | More complex to implement, requires careful error handling |
Third-party libraries | Libraries offering parsing functionalities | Additional features like error handling, advanced parsing | Might introduce additional dependencies |