For a given string str there are several ways to do this, each of which has its advantages and disadvantages. I wrote a live example here: https://ideone.com/LO2Qnq and discussed each of them below:
As suggested here, the strtol out parameter can be used to get the number of characters read. strtol actually returns long not int so when casting, a cast occurs.
char* size; const int num = strtol(i.c_str(), &size, 10); if(distance(i.c_str(), const_cast<const char*>(size)) == i.size()) { cout << "strtol: " << num << endl; } else { cout << "strtol: error\n"; }
Note that i.c_str() is used here to refer to the same line. c_str Returns a pointer to a base array that serves as a symbol repository, not temporary if you have C ++ 11:
c_str() and data() perform the same function
Also note that the pointer returned by c_str will be valid between strtol and distance if:
- Passing non-
const reference to string in any standard library function
- A non-
const function call - members on a string , with the exception of operator[] , at() , front() , back() , begin() , rbegin() , end() and rend()
If any of these cases is violated, you need to make a temporary copy of i that is the basis of const char* and run a test on this.
sscanf can use %zn to return the number of characters read, which may be more intuitive than comparing pointers. If the base is important, sscanf may not be a good choice. Unlike stoi and stoi , which support bases 2 - 36, sscanf provides the qualifier only octal ( %o ), decimal ( %d ) and hexadecimal ( %x ).
size_t size; int num; if(sscanf(i.c_str(), "%d%zn", &num, &size) == 1 && size == i.size()) { cout << "sscanf: " << num << endl; } else { cout << "sscanf: error\n"; }
As suggested here, the output parameter stoi works like sscanf %n returning the number of characters read. According to C ++, this takes string and, unlike the C implementations above, stoi throws invalid_argument if the first non-space character is not considered a digit for the current base, and this, unfortunately, means that unlike C implementations, this should check for an error in try and catch blocks.
try { size_t size; const auto num = stoi(i, &size); if(size == i.size()) { cout << "stoi: " << num << endl; } else { throw invalid_argument("invalid stoi argument"); } } catch(const invalid_argument& ) { cout << "stoi: error\n"; }