1

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.

4
  • It doesn't work because your looping condition is "it's a digit", so while it's a digit add it to v[i]. And what if the string doesn't start with a digit? Commented Jun 26, 2017 at 18:13
  • But if it's not a digit it won't do anything? I don't understand because it won't work even if I use. if (s[i]>='0' && s[i]<='9) { while (s[i]>='0' && s[i]<='9) v[i].push_back(s[i]); i++; }, Commented Jun 26, 2017 at 18:21
  • what do you think happens to i on the line while (s[i]>='0' && s[i]<='9) v[i].push_back(s[i]);? Commented Jun 27, 2017 at 10:21
  • this code is going to loop forever, you dont increment i in your while loop Commented Jun 28, 2017 at 16:28

4 Answers 4

2

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'; }
);
Sign up to request clarification or add additional context in comments.

1 Comment

I agree, but that "I can only use for loop and pointers" in OP question really clashes with that C++11 tag...
1

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];
        }
    }
} 

3 Comments

Your loop end condition should be i < s.length(). Your current code will skip the last character or do something even worse if the string is empty.
Even if restricting to ASCII may be fine, consider using '0' and '9' to increase readabiltiy of the code.
@Bob__ yes I totally agree with you
1

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]);
   }
}

Comments

1
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);
  }   
}

2 Comments

Do you mind elaborate? Even if the code posted may answer the question, an explanation could be beneficial to others and increase its value.
First, we create a string object will be used as a test, then a vector where all digits will be stored. Then the for loop iterates over the string. Each character in the string is checked to see if it is a digit or not. If it is then it is added to the vector.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.