Reputation: 49
I tried doing this to some substrings which were all natural numbers
fi = stoi(f[i]) - stoi(s[i]);
se = stoi(s[i]) - stoi(f[i]);
where f and s are 2 strings. This was solved when I assigned the part of the string to a new variable. I experienced similar stuff with atoi(str.c_str()). Why does stoi and atoi behave like this?
Upvotes: 0
Views: 1986
Reputation: 597051
If f
and s
are string
s, then f[i]
and s[i]
are single char
s. atoi()
and std::stoi()
do not take single char
s as input. They are simply not designed to work that way.
atoi()
takes a const char*
as input, and expects it to be a pointer to a null-terminated C-style string. So, to pass it a single char
, you will have to construct a char[2]
array first, eg:
char arr[] = { f[i], '\0' };
int i = atoi(arr);
std::stoi()
takes a std::string
as input. To pass it a single char
, you have to construct a 1-char std::string
first. However, std::string
does not have a constructor that accepts only a single char
as input, but there are many different ways that you can produce a 1-char std::string
, eg:
std::string s(1, f[i]);
int i = std::stoi(s);
std::string s(f, i, 1);
int i = std::stoi(s);
std::string s(&f[i], 1);
int i = std::stoi(s);
std::string s(f+i, f+(i+1)); // if f is a char[]/char*
int i = std::stoi(s);
std::string s(f.begin()+i, f.begin()+(i+1)); // if f is a std::string
int i = std::stoi(s);
std::string s = f.substr(i, 1); // if f is a std::string
int i = std::stoi(s);
std::string s = { f[i] };
int i = std::stoi(s);
std::string s;
s = f[i]; // std::string has an operator=(char) overload
int i = std::stoi(s);
std::string s;
s.resize(1);;
s[0] = f[i];
int i = std::stoi(s);
std::string s = std::string_view(&f[i], 1);
int i = std::stoi(s);
That being said, if all of the char
s are between '0'
..'9'
inclusive, then you don't need to use atoi()
/std::stoi()
to convert them to integers. Just subtract '0'
from them instead, eg:
fi = (f[i] - '0') - (s[i] - '0');
se = (s[i] - '0') - (f[i] - '0');
This works because in ASCII, characters '0'
..'9'
are defined as sequential values 48..57, thus the above is really just doing this:
'0' - '0' = 0
-> 48 - 48 = 0
'1' - '0' = 1
-> 49 - 48 = 1
'2' - '0' = 2
-> 50 - 48 = 2
and so on...
Upvotes: 1
Reputation: 44268
Why can't part of a string be passed onto atoi or stoi?
It can, to get a substring from std::string
you need to call std::string::substr()
method. Something like:
std::stoi( f.substr( i, 1 ) );
assuming you want 1 symbol substring long starting from position i
. std::string::operator[]
does not give you a substring, but a single character from that position, ie std::string
can act as a container of chars.
Upvotes: 4