To convert a std::string
to an int
in C++, there are several methods, each with its own use cases and error-handling strategies. Below is a detailed explanation with examples:
1. Using std::stoi()
(C++11 and later)
The std::stoi()
function (from <string>
) converts a string to an integer and throws exceptions for invalid inputs.
Basic Example:
#include <string>
#include <iostream>
int main() {
std::string str = "12345";
try {
int num = std::stoi(str);
std::cout << "Converted: " << num << std::endl;
} catch (const std::invalid_argument& e) {
std::cerr << "Invalid argument: " << e.what() << std::endl;
} catch (const std::out_of_range& e) {
std::cerr << "Out of range: " << e.what() << std::endl;
}
return 0;
}
Check Entire String Validity:
Use the optional size_t* pos
parameter to ensure the entire string is parsed:
std::string str = "123abc";
size_t pos;
try {
int num = std::stoi(str, &pos);
if (pos != str.size()) {
std::cout << "Invalid characters after number!" << std::endl;
} else {
std::cout << "Valid: " << num << std::endl;
}
} catch (...) { /* Handle exceptions */ }
2. Using std::istringstream
(Works in Older C++ Standards)
Leverage string streams (<sstream>
) to parse the string and validate it fully.
Example:
#include <sstream>
#include <string>
#include <iostream>
int main() {
std::string str = " 6789"; // Leading whitespace allowed
std::istringstream iss(str);
int num;
// Extract the integer and check for trailing characters
if (iss >> num) {
char remaining;
if (iss >> remaining) { // Check leftover characters
std::cout << "Invalid trailing characters!" << std::endl;
} else {
std::cout << "Converted: " << num << std::endl;
}
} else {
std::cout << "Conversion failed!" << std::endl;
}
return 0;
}
3. Using C Functions (strtol()
or atoi()
)
For compatibility with older codebases or C-style validation.
Example with strtol()
(Robust Error Handling):
#include <cstdlib>
#include <string>
#include <iostream>
#include <cerrno> // For errno
int main() {
std::string str = "2147483648"; // Exceeds int range
char* end;
const char* cstr = str.c_str();
long num = std::strtol(cstr, &end, 10); // Base 10
if (cstr == end) {
std::cout << "No digits found!" << std::endl;
} else if (*end != '\0') {
std::cout << "Invalid trailing characters!" << std::endl;
} else if (errno == ERANGE || num < INT_MIN || num > INT_MAX) {
std::cout << "Out of int range!" << std::endl;
} else {
int result = static_cast<int>(num);
std::cout << "Converted: " << result << std::endl;
}
return 0;
}
Example with atoi()
(Simple but Limited):
#include <cstdlib>
#include <string>
#include <iostream>
int main() {
std::string str = "123";
int num = std::atoi(str.c_str());
std::cout << "Converted: " << num << std::endl;
return 0;
}
Note: atoi()
returns 0
for invalid inputs (e.g., "abc"
), making it unreliable for error checking.
Key Differences
Method | Pros | Cons |
---|---|---|
std::stoi() | Simple, robust error handling | Requires C++11, throws exceptions |
std::istringstream | Works in older C++ standards | Verbose, limited error messages |
strtol() | Precise control, C compatible | Manual error checking, returns long |
atoi() | Simple syntax | No error handling, deprecated in C++ |
Handling Edge Cases
- Leading/Trailing Whitespace:
std::stoi()
andstd::istringstream
ignore leading whitespace.- Use
pos
or stream checks to detect trailing characters.
- Hexadecimal/Binary Strings:
- Use
std::stoi(str, nullptr, 16)
for hex orstd::stoi(str, nullptr, 2)
for binary.
- Overflow/Underflow:
std::stoi()
throwsstd::out_of_range
for values exceedingint
limits.strtol()
setserrno = ERANGE
for overflow.
Summary
- For Modern C++: Use
std::stoi()
with exception handling. - For Legacy Code: Use
std::istringstream
orstrtol()
. - Avoid
atoi()
: It lacks reliable error detection.
Choose the method based on your project’s C++ version and error-handling requirements.