Simplifying switch cases

The code below is a section of the switch statement that I want to simplify. Between comment (1), you can see a code that checks for sequence of numbers in a string. i.e, string = 123abc45, then the numberRecorder will record a node with number 123, and another node with number 45, and then linking the two nodes with pointers. While on the other hand, the string recorder, numberRecorder_str, will record "123, 45".

1. Is there a better way to check for sequence of numbers than writing cases from 0 to 9 and then making a while loop to check if the next literal in a string is also a number? For example, is there a way to collapse case 0, case 1, .. case 9, and the while loop that checks for consecutive digits into one case?

2. Also, is there an easy way to check if a sequence of characters in a string is a number, such as int or double, other than including <cctype> and using isdigit() function?

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

#include "Numbers.h"
#include <cctype>

...

int numberRecorder_length=0;
string numberRecorder_str

string test:: FindingNumbers(const string &str)
{
for (unsigned int i = 0; i<str.length(); i++) 
{


	switch (str[i])
	{
                //(1) BEGIN: Finding if the string literal contains a sequence of numbers and recording it if it is:
		case 0: 
		case 1: 
		case 2: 	
		case 3: 	
		case 4: 
		case 5: 
		case 6: 
		case 7: 
		case 8: 
		case 9:	
		{
			string number;
			number = number + str[i]; //Add char type to string so we can append the string.

			while(isdigit(str[i+1])) 
			{

			        number = number + str[i+1]; //Add char type to string so we can append the string.

				i++;
			}
               //(1) END: Finding if the string literal contains a sequence of numbers and recording it if it is.

                        //numberRecorder is the private member variable and records the numbers in the string as a stack of pointer-linked nodes.
			numberRecorder.Push(number);
                        //numberRecorder_length counts the number of items in numberRecorder.
			numberRecorder_length++;

			//This if statement is for keeping track of commas.
			if(numberRecorder_length>1)
				numberRecorder_str = numberRecorder_str + ", ";
                      
                        //Finally we add the number to the string version of numberRecorder, numberRecorder_str:
			numberRecorder_str = numberRecorder_str + number;

			break;

		}
           ...
          }
   ...
}
Last edited on
Just use isdigit(). That's what it's there for.
Solution using custom character table:
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
#include <iostream>
#include <string>
#include <sstream>
#include <locale>
#include <vector>

struct extract_int : std::ctype<char> {
    static const mask* make_table()
    {
        static std::vector<mask> v(classic_table(), classic_table() + table_size);
        for(auto& c: v)
            c |= space; //Threat every character as space
        for(char c = '0'; c < '9'; ++c)
            v[c] &= ~space; //Aside from digits
        return v.data();
    }
    extract_int(std::size_t refs = 0) : ctype(make_table(), false, refs) {}
};

std::string findingNumbers(const std::string& str)
{
    std::istringstream inp(str);
    inp.imbue(std::locale(inp.getloc(), new extract_int));
    std::ostringstream out;
    int temp;
    bool first = true;
    while(inp >> temp) {
        if (!first)
            out << ", ";
        out << temp;
        first = false;
    }
    return out.str();
}

int main()
{
    std::cout << findingNumbers("123as 53as77s1");
}
123, 53, 77, 1
Last edited on
Topic archived. No new replies allowed.