简体   繁体   中英

C++ extracting ints from a string

I'm trying to extract integers from a string, for example user input could be 5ft12in or 5'12"`.

However, the code works when my input is 5ft1in , but not when it is 5ft12in .

I want to loop through the whole string and extract 3 numbers, as such:

feet = 5 
inches 1 =1 
inches 2 = 2   

But I cant seem to find the problem.

I think there is a way to convert the input to stringstream and then peek through the whole string using char , but I'm not quite sure how.

string feet = "";
string inches = "";
string inches2 = "";

for (int i = 0; i < height.size(); ++i) {
    if (isdigit(height[i]) && (feet.empty())) {
        feet = height[i];
    } // end if

    else if ((isdigit(height[i]) && (!feet.empty()))) {
        inches = height[i];
    }

    else if ((isdigit(height[i]) && (!feet.empty() && (!inches.empty())))) {
        inches2 = height[i];
    } // end else if

}//end for

cout << "String of feet : " << feet << endl;
cout << "String of inches 1 : " << inches << endl;
cout << "String of inches 2 : " << inches2 << endl;

In your second if condition, you are not checking the value of inches , if it is empty or not. Thus, when the "2" from your string "5ft12in" gets checked in the second if condition, it very much satisfies it. Therefore, resulting in again storing the value "2" in inches , which you actually wanted to store in inches2 .

Solution :

string feet = "";

string inches = "";

string inches2 = "";

for(int i = 0; i < height.size(); ++i)
{

    if (isdigit(height[i]) && (feet.empty())) {         
        feet = height[i];
    } // end if 

    else if ((isdigit(height[i]) && (!feet.empty()) && (inches.empty())) {
            inches = height[i];
        }
    else if ((isdigit(height[i]) && (!feet.empty() && 
    (!inches.empty())))) {
            inches2 = height[i];
        } // end else if 

}//end for


    cout << "String of feet : " << feet << endl;
    cout << "String of inches 1 : " << inches << endl;
    cout << "String of inches 2 : " << inches2 << endl;

You don't need the loop at all.

Look at the find_first_of() and find_first_not_of() methods of std::string , for example:

std::string feet;
std::string inches;

std::string::size_type i = height.find_first_not_of("0123456789");
feet = height.substr(0, i);

std::string::size_type j = find_first_of("0123456789", i);
i = height.find_first_not_of("0123456789", j);
if (i == std::string::npos) i = height.size();

inches = height.substr(j, i-j);

std::cout << "feet : " << feet << std::endl;
std::cout << "inches : " << inches << std::endl;

However, this kind of pattern searching would be better handled using std::regex() instead (C++11 and later only):

#include <regex>

std::string feet;    
std::string inches;

std::smatch sm;
std::regex_match(height, sm, std::regex("(\\d+)\\D+(\\d+)\\D+"));
if (sm.size() == 3)
{
    feet = sm.str(1);
    inches = sm.str(2);
}

std::cout << "feet : " << feet << std::endl;
std::cout << "inches : " << inches << std::endl;

Or std::sscanf() :

#include <cstdio>

int feet, inches;

std::sscanf(height.c_str(), "%d%*[^0-9]%d", &feet, &inches);

std::cout << "feet : " << feet << std::endl;
std::cout << "inches : " << inches << std::endl;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM