Previously discussed Convert Char to Int in C++, in which we converted a single character to an integer. In this article we will build upon that idea by converting multiple characters to an integer.
C++ Standard Library
If want to use the built-in functions, the C++ standard has a couple built-in functions for converting strings to an integer. Namely there is atoi
and std::stoi
.
atoi
atoi
is part of “C Standard General Utilities Library in the header <cstdlib>
.
#include <cstdlib> // atoi
#include <cstdio> // printf
int main()
{
const char* buffer = "123456";
int num;
// int atoi(const char *buffer);
num = atoi(buffer);
if (num == 0)
{
// error
printf("Could not convert number");
}
else
{
// output value
printf("Number is %d\n", num);
}
return 0;
}
Notes: atoi
returns 0
on error, which can be confusing if the input was intended to be zero. If the converted value is outside the range of int
then it is undefined behavior.
stoi
stoi
is part standard name space and is in the C++ <string>
header. stoi
has the added benefit of being able to convert different bases.
#include <string> // std::string
#include <iostream> // std::cout
int main()
{
using namespace std;
string str1 = "12345"; // decimal number (base 10)
string str2 = " 123 abcd"; // can be part of string, but has to part of the beginning
string str3 = "c0ffee"; // base 16
string str4 = "0xff"; // can auto detect
int num1 = stoi(str1); // default is Idx = nullptr, Base = 10
int num2 = stoi(str2, nullptr, 10);
int num3 = stoi(str3, nullptr, 16);
int num4 = stoi(str4, nullptr, 0); // can auto detect
cout << str1 << " -> " << num1 << endl;
cout << str2 << " -> " << num2 << endl;
cout << str3 << " -> " << num3 << endl;
cout << str4 << " -> " << num4 << endl;
return 0;
}
The difference between atoi and stoi
Unless C strings must be used, then it is advisable to use stoi instead. One pitfall of atoi
is that returns 0
on error, which can be valid input to the function. If stoi
can’t converted the buffer into an integer it throws an exception (either invalid_argument
or out_of_range
exception).
We can see that C++ stoi
has more safety features than C atoi
, which comes at the cost of dealing with exceptions.
Convert multiple characters to a single int
We can iterate on the idea of converting one character into converting multiple characters into an integer. The interesting part of this algorithm is the computation of the result. It is done by 10 * result + ch - '0'
. First, the ones digit is computed by ch - '0'
. Next, the result is shifted by 10. Then the new digit added.
Initialization:
result = 0
Iteration 1:
digit = 1
result = 10 * result + digit = 1
Iteration 2:
digit = 2
result = 10 * result + digit = 10 + 2 = 12
Iteration 3:
digit = 3
result = 10 * result + digit = 120 + 3 = 123
Iteration 4:
digit = 4
result = 10 * result + digit = 1230 + 4 = 1234 // final result
We can represent this idea in code:
unsigned int my_stoi(string s)
{
unsigned int result = 0;
for (char ch : s)
{
if (isdigit(ch))
{
int digit = ch - '0';
result = 10 * result;
result = result + digit;
}
}
return result;
}
Note that this is only a sketch of what the algorithm should be. For example, the down side to this is we can have a string that is longer than what can fit into an integer (i.e., out of range). We can use a larger integer type, such as unt64_t
but this too has a limitation on how many digits can be converted. The second assumption it makes is that the number is positive. Third assumption it makes that there is no extra whitespace around or between the digits (in this algorithm it ignores it). This exercise can be left with the reader to