Reputation: 7
Can you please help me find digits in string without using functions like isdigit? I can only use for loop and pointers. If I have
std::string s {"A year has 365 days"}
Why can't I do something like this:
for (int i=0; i<s.size(); i++){
while (s[i]>='0' && s[i]<='9) v[i].push_back(s[i]);
}
I know this would store digits 3 6 and 5 in vector and not number 365. But I don't understand why my while loop doesn't work.
Upvotes: 1
Views: 1688
Reputation: 484
if I'm understanding you correctly, you want to store just the digits? If so then maybe you are looking for something like this:
string s = "A year has 365 days";
vector<string> storedNums = {};
for(int i = 0; i < (s.length() - 1); i++) {
if (s[i] >= 48 && s[i] <= 57) {
storedNums.push_back(s[i]);
}
}
Here I'm using the ascii values between 48 and 57 (digit chars) to decipher if the current character is a digit. Using the while loop will put you in an infinite loop if the condition is true. This means once your iteration reached '3', it will continue to sit in the while loop. So your vector will keep calling push_back forever because the current condition is met and does not have a base case to break out of the while loop.
Edit:
This code has two mistakes that I did not initially catch. First, the vector should be a vector<char>
and not a vector<string>
. Second, it has come to my attention that the condition should not be i < s.length()-1
and it should be i < s.length()
. The way I initially typed skips the last index in the loop and it works with the given string, however if "days" is taken out of the string, it will only print 36
. The following code has been adjusted for readability and has been compiled to make sure it works:
// Example program
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
string s = "A year is 365";
vector<char> nums;
int length = s.length();
for(int i = 0; i < length; i++) {
if (s[i] >= '0' && s[i] <= '9') {
nums.push_back(s[i]);
cout << s[i];
}
}
}
Upvotes: 1
Reputation: 18652
You're looping over a sequence and conditionally copying elements to another container. The standard library has a std::copy_if
algorithm specifically for this task.
std::string s{ "A year has 365 days" };
std::vector<char> v;
std::copy_if(s.begin(), s.end(), std::back_inserter(v), ::isdigit);
If you insist on not using isdigit
you can provide your own predicate (a lambda in this example).
std::copy_if(s.begin(), s.end(), std::back_inserter(v),
[](char ch) { return '0' <= ch && ch <= '9'; }
);
Upvotes: 2
Reputation: 2157
std::string str {"A year has 365 days"};
std::vector<char> vec;
for(const char c: str)
{
if (c>='0' && c<='9')
{
vec.push_back(c);
}
}
Upvotes: 1
Reputation: 206737
Why can't I do something like this:
for (int i=0; i<s.size(); i++){ while (s[i]>='0' && s[i]<='9') v[i].push_back(s[i]); }
That won't work because the program will execute the while
statement for ever if the conditional were true
. You need to use if
fnstead of while
.
for (int i=0; i<s.size(); i++)
{
if (s[i]>='0' && s[i]<='9')
{
v[i].push_back(s[i]);
}
}
Upvotes: 1