Thread: Extract complete integers from string

  1. #1
    Registered User
    Join Date
    May 2008
    Posts
    115

    Extract complete integers from string

    Hi

    I have strings that look like

    "Answer: 1/3242"
    "Answer: 132/643"
    "Answer: 5/631543"

    etc., and I need to compute the value of the fraction by e.g. extracting the top and bottom as substrings.

    My first idea was to modify the two functions below, which search for the first and the last digit, to search for the first and the last series of digits. But this does not quite work. Are there simple ways to do this?

    Code:
    int top_frac(const std::string& x)
    {
    	std::string temp;
    	int number = 0;
    
    	for ( unsigned int i = 1; i < x.size(); i++ ) {
    		if ( isdigit( x[i] ) ) {
    			for ( unsigned int a = i; a < x.size(); a++ ) {
    				temp += x[a];
    			}
    			break;
    		}
    	}
    	std::istringstream stream( temp );
    	stream >> number;
    	return number;
    }
    
    int bot_frac(const std::string& x)
    {
    	std::string temp;
    	int number = 0;
    
    	for ( unsigned int i = x.size(); i--; ) {
    		if ( isdigit( x[i] ) ) {
    			for ( unsigned int a = i; a < x.size(); a++ ) {
    				temp += x[a];
    			}
    			break;
    		}
    	}
    	std::istringstream stream( temp );
    	stream >> number;
    	return number;
    }
    Thank you for your help!
    serge

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I suggest to start by removing the "Answer: " substring. A fairly direct way to do this is to observe that "Answer: " has a length of 8, so you take the substring starting from index 8 (remember to use named constants rather than magic numbers, or otherwise compute the length of "Answer: ").

    With this substring, e.g., "132/643", you have a few ways by which you can extract 132 and 643. One approach is to turn it into a stringstream, and then use formatted input to read into an int, then a char, then an int.

    Another approach is to use the find member function of std::string to find the '/', then get two substrings "132" and "643", and then convert them to int, e.g., by using a stringstream as in your current code.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    May 2008
    Posts
    115
    Quote Originally Posted by laserlight View Post
    I suggest to start by removing the "Answer: " substring. A fairly direct way to do this is to observe that "Answer: " has a length of 8, so you take the substring starting from index 8 (remember to use named constants rather than magic numbers, or otherwise compute the length of "Answer: ").

    With this substring, e.g., "132/643", you have a few ways by which you can extract 132 and 643. One approach is to turn it into a stringstream, and then use formatted input to read into an int, then a char, then an int.

    Another approach is to use the find member function of std::string to find the '/', then get two substrings "132" and "643", and then convert them to int, e.g., by using a stringstream as in your current code.
    Thanks for the inspiration. This is what I put together after finding a nice split function on the internet:

    Code:
    #include <iostream>
    #include <iterator>
    #include <fstream>
    #include <vector>
    #include <algorithm>
    #include <string>
    #include <sstream>
    #include <stdio.h>
    
    std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
    	std::stringstream ss(s);
    	std::string item;
    	while (std::getline(ss, item, delim)) {
    		elems.push_back(item);
    	}
    	return elems;
    }
    
    std::vector<std::string> split(const std::string &s, char delim) {
    	std::vector<std::string> elems;
    	split(s, delim, elems);
    	return elems;
    }
    
    int main(int argc, char* argv[])
    {
    	std::string str("      Answer : 1/128");
    	std::string lookup("Answer");
    	
    	if ( str.find(lookup) != std::string::npos ) {
    			unsigned numpos = str.find("Answer");
    			std::string numstr = str.substr( numpos + 9 );
    			std::vector<std::string> x = split(numstr, '/');
    			// for ( std::vector<std::string>::iterator it1 = x.begin(); it1 != x.end(); ++it1 ) std::cout << *it1 << " ; ";
    			std::cout << std::endl;
    			std::cout << (double) atoi( x[0].c_str() ) / atoi( x[1].c_str() ) << std::endl;
    	}
    
    	return 0;
    }

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    The standard library really lacks some practical algorithms such as splitting a string, even in this modern age...
    But wait, there's a solution. Enter boost.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    That's not bad, serge, but is using magic values (like 9).

    Personally, I'd check if it contains the string "Answer" at the beginning, form a string by discarding anything other than digits, the '/' characters, and (maybe) sign characters ('+' or '-'). Then parse what's left as if it's a set of integral values separated by '/'. Depending on needs, it may be a good idea to cope with "Answer 2" (i.e. the absence of a '/') rather than barfing, as well as cope with "answer 3/4" (case insensitive).

    The necessary amount of error checking, and ability to cope with extraneous characters, depend on how reliable the source of input is. It could, if needed, cope with "AnSwer 6/-2/3 from winnie the poo" (by giving a result of -1, reporting presence of extraneous characters, etc etc).
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Extract Words from String
    By Coding in forum C++ Programming
    Replies: 12
    Last Post: 03-07-2008, 04:22 AM
  2. how to extract words from a string
    By panfilero in forum C Programming
    Replies: 7
    Last Post: 11-04-2005, 08:06 AM
  3. Extract integer value from STL string
    By ChadJohnson in forum C++ Programming
    Replies: 10
    Last Post: 03-15-2005, 02:39 AM
  4. How to extract a hex value from a string?
    By dlaw in forum C++ Programming
    Replies: 2
    Last Post: 04-17-2002, 02:11 PM
  5. Extract numbers as integers from a string array
    By DarthC in forum C++ Programming
    Replies: 2
    Last Post: 03-23-2002, 05:09 PM