Extracting numbers from a string

So, I have a string and I need to extract numbers from it. I've tried different things but they are not working. So, Here is what I have:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

int main()
{
	string myString;
	char *strPtr;
	
	cout << "Enter a string to evaluate: " << endl;
	getline(cin, myString);

	strPtr = new char[myString.length() + 1];

	for (int i = 0; i < myString.length(); i++)
	{
		strPtr[i] = myString[i];
	}
	
        strPtr[myString.length()] = '\0';

	for (int i = (myString.length() - 1); i >= 0; i--)
	{
		if (isdigit(strPtr[i]))
		{
			//Here is where I don't know what to do
                        //Please help
		}
	}
	
	return 0;
}
Do you know if you get into the if statement on line 23? If you put a cout statement there (something like cout << "HERE";) and input a string with a number int it, does the program output that statement?

Once you know you get there, you need to know what you need to do with that number.

For example, do you just need to print out that number? Or do you need to store it in another string?
I actually need to store each number into a stack. However, I would love to know how to output each number.

Do I need to record how many places each number has and then construct the number based on ones, tens, hundreds, thousands, etc?
Let's take it one step at a time. Your code actually does a lot already. (It successfully captures single digit numbers in the string.)

1) Let's prove that your program captures single digit numbers. Add a cout statement in your if(isdigit) if statement, and have it output the current array element. Try it on strings with single-digit numbers in them. (For example, a1b2c3d4)

2) Now try another string with that code that has 2 or 3 digit numbers in it. So something like a123b24cd. Notice it only captures 1-digit numbers.

3) Modify your code to capture multi-digit numbers. Here's two ideas:
- You could save each digit into a string, and the next-nondigit character marks the end of your number.
- You could save the beginning index, and the next-nondigit character marks the end index of your number.

Try to get that working. So that a123b24cd will return 123 and 24 (note that your loop goes backwards through the string, so you will either need to reverse your numbers you capture or change the direction your loop goes... otherwise you will get 42 and 321 as your numbers).

Once you have that working, we can look into storing them into a stack.

Also... we need some more information for the next part (the stack):
* What is the maximum size of a number that can be in the string? Could I have 999999999999999999999999999999, or is the max 256, or something else? This will tell us the data type we can use for the stack.
* Are you supposed to implement a stack, or can you use the standard library (std::stack)?
I modified a little bit your original code as below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <vector>

using namespace std;

int main()
{
        string myString;
	vector<int> numbers;
	int num = 0;

	cout << "Enter a string to evaluate: " << endl;
	getline(cin, myString);

	for (int i = 0; i < (int)myString.length(); i++) {
		if (isdigit(myString[i])) {
		    // '1' - '0' = 1, '2' - '0' = 2
		    num = (num * 10) + (myString[i] - '0');
		}
		else {
                     //save the number found if non-digit character is found if it is not 0
                     if (num > 0) {
                          numbers.push_back(num);
                          num = 0;
                     }
		}
	}

	// Save the last number if not zero
	if (num > 0) {
              numbers.push_back(num);
	}

    // Display numbers found
    cout << "Displaying numbers found in string \"" << myString << "\"" << endl;
    for (int i = 0 ; i < (int)numbers.size(); i++) {
        cout << "numbers[" << i << "] = " << numbers[i] << endl;
    }
    return 0;
}


Try that as it worked for me based on my understanding on what you want to achieve.
Last edited on
To tscott8706:

For the stack, we can expect a reasonable number. I am working on a calculator program that accepts a string of operators and operands in polish notation, and uses the stack to perform operations. So, the whole string will not be longer than one line. Example:

- 5 * 4 2, which is equivalent to 5-(4*2).

So, given this string, I start at the end of it and check if the last element (the element before the null terminator) is a digit. If it is a digit, I need to continue checking for more digits until the element is not a digit. Then, I need to somehow construct a number and store it in the bottom of the stack. Then, continue looking for the next number in the same manner and store it on top of the previous number. Do this until I run into one of the 4 operators we're working with. One I run into an operator, I need to take top 2 numbers from the stack, perform an operation and then store the result on top. Continue in this manner until I am left with just one number in the stack and then output it as a result. I also need to throw an exception when the given string doesn't have enough operands.
to tanezavm:

Thank you very much for taking your time to write the code and help me. I appreciate it. But I tried compiling it in my Visual Studio and it won't compile. I will highlight the underlined parts.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <vector>

using namespace std;

int main()
{
        string myString;
	vector<int> numbers;
	int num = 0;

	cout << "Enter a string to evaluate: " << endl;
	getline(cin, myString);

	for (int i = 0; i < (int)myString.length(); i++) {
		if (isdigit(myString[i])) {
		    // '1' - '0' = 1, '2' - '0' = 2
		    num = (num * 10) + (myString[i] - '0');
		}
		else {
                     //save the number found if non-digit character is found if it is not 0
                     if (num > 0) {
                          numbers.push_back(num);
                          num = 0;
                     }
		}
	}

	// Save the last number if not zero
	if (num > 0) {
              numbers.push_back(num);
	}

    // Display numbers found
    cout << "Displaying numbers found in string \"" << myString << "\"" << endl; //In this line, the second << is underlined in VS
    for (int i = 0 ; i < (int)numbers.size(); i++) {
        cout << "numbers[" << i << "] = " << numbers[i] << endl;
    }
    return 0;
}
Last edited on
Ok, so that's why you are working backwards (Polish notation).

As a reference, here's the operators for a std::stack: http://www.cplusplus.com/reference/stack/stack/

So the logic you have to implement in your program is at line 21. So if it is a digit, then you can push it onto the stack.

If it is not a digit, you need to check if it is an operator. If it is not an operator, throw an error.

If it is an operator, you need to check if there are at least two digits on the top of the stack (use pop twice). If those two elements you popped are not digits, you can end the program and throw an error.

So let's look at that in pseudocode (this is in your for loop that goes backwards through the string).
1
2
3
4
5
6
7
8
9
10
11
12
13
/*
if char is a digit
    push onto the stack
else if char is an operator
    pop twice, getting the two most recent characters
    if two characters are not digits
        throw error
    else
        perform operation
        push result onto the stack
else
    throw error
*/


I'm not terribly familiar with Polish notation, so that might not be exactly correct. But at least it gives you something to work with.
to tscott8706:

I can't just push a digit onto the stack. I have to push a number on the stack as it may be 2, 3, or 4 digit number or more. So, how do I get the whole number? For example, what if the string given is

- 56 * 472 2941

How do I

1
2
3
4
5
6
7
8
9
stack.push(2941);
stack.push(472);
stack.push(stack.pop(x) * stack.pop(x));
stack.push(56);
stack.push(stack.pop(x) - stack.pop(x));

stack.pop(x);

cout << "The result is: " << x << endl;
The stack should be of type integer (or whatever number type you need).

Before you push onto the stack, convert the string to an integer.

You can use atoi to do this. http://www.cplusplus.com/reference/cstdlib/atoi/

If it is a string rather than a character array, you can still use atoi by doing [your string variable].c_str().
to tanezavm:

Hey, bud, thank you very much for your help. I kept looking at your code to figure out what was wrong and found the problem. I guess you forgot to include the line #include <string> . I did that and it worked. Like a charm. Thanks again.
Topic archived. No new replies allowed.