Thread: getting numbers from a string

  1. #1
    Registered User
    Join Date
    Oct 2002
    Posts
    69

    getting numbers from a string

    i can't figure this out........ we have to have a string input in the form of {int,int,int, etc.....} and then i want to put those int values into an array of some sort. how can you get the values from the string put into integer values? it seems hard to get it to recognize that the whole set of numbers leading up to each comma represents one single value, not a collection of however many digits it is composed of.

  2. #2
    C++ Developer XSquared's Avatar
    Join Date
    Jun 2002
    Location
    Ontario, Canada
    Posts
    2,718
    sscanf
    Naturally I didn't feel inspired enough to read all the links for you, since I already slaved away for long hours under a blistering sun pressing the search button after typing four whole words! - Quzah

    You. Fetch me my copy of the Wall Street Journal. You two, fight to the death - Stewie

  3. #3
    Registered User
    Join Date
    Nov 2002
    Posts
    1,109
    parse the string using the find() fxn and find the comma. then take the number before the comma and substring it. and then turn that into an int using atoi() or itoa(). I don't remember which. you may want to try a search to find out which, as well as other fxns for int to string or string to int.

    edit: XSquared beat me.

  4. #4
    Registered User
    Join Date
    Oct 2002
    Posts
    69
    pardon my ignorance, but what exactly is a substring and how do i use it? when i was looking through the boards about substrings and other stuff, they all reference pointers, but we haven't learned about that yet. i'm in the process of reading the faq on pointers, so i'll get back to this in a little bit

  5. #5
    Registered User
    Join Date
    Nov 2002
    Posts
    1,109
    here is an example of what I think you are trying to accomplish:
    Code:
    #include <iostream>
    #include <string>
    
    int main()
    {
    	std::string example = "123, 758"; //string with two ints, separated by a comma
    	std::string temp; //declare for the substring
    	const char comma = ','; //what you need to find
    	int found = example.find(comma); //the find fxn returns an int
    	
    	temp = example.substr(0, found); //the substr fxn takes a string from 
    	//(where you want to start, where you want to end) and assigns your temp
    	//string the value
    	
    	std::cout << temp << std::endl;
    	return 0;
    }
    Output:

    123

    edit: for multiple ints, just do something like this in a loop.

  6. #6
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    Why not just read the FAQ? That's what it's there for.

    -Prelude
    My best code is written with the delete key.

  7. #7
    Registered User
    Join Date
    Oct 2002
    Posts
    69
    now, how can you make a c string that takes its input from the user? i was reading my programming book and the example you gave, but they look like the string has to start out defined, such as
    std::string example = "123, 758";

    does this mean the example string is set to 123,758 to begin with?

  8. #8
    Registered User
    Join Date
    Oct 2002
    Posts
    69
    ok, i know what i didn't say before...... that code up there makes a string and reads the value character by character into the string, right? i need something to get the integer value of the entire number from the input string. so someone would input {3,4,100} and the program would extract 3 to one position in an array or a variable, 4 to another variable, and 100 to another variable. that is why this program is confusing me!

  9. #9
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    Using a C-string, one of many solutions would be to use strtok and atoi from cstring and cstdlib, respectively.
    Code:
    // Ugly example, but you should get the idea
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    
    using std::cout;
    using std::endl;
    using std::cin;
    
    int main()
    {
      char buf[BUFSIZ];
    
      cout<<"Enter a set of three numbers (ex. {3,4,100}): ";
      cin.getline ( buf, sizeof buf );
    
      // Assume enclosing braces and three numbers
      char *p = buf;
      char *t = strtok ( p, " ,{}" );
      int vals[3];
      int i = 0;
    
      while ( t != 0 && i < 3 ) {
        vals[i++] = std::atoi ( t );
    
        t = strtok ( 0, " ,{}" );
      }
    
      for ( i = 0; i < 3; i++ )
        cout<< vals[i] <<endl;
    }
    -Prelude
    My best code is written with the delete key.

  10. #10
    Registered User
    Join Date
    Jan 2003
    Posts
    311

    perils of parsing

    There are many ways to do this, C++ provides some primitive but powerfull tools. Parsing from a std::string usually consists of using the find members to get the positions of tokens you are interested in, then using substring to create a new string consisting of nothing but token. substr(pos,len) makes a copy of a string starting at the pos and is of length len (or length pos to end of string) whichever is less.

    There are two ways to read from a stream into a std::string either
    cin >> str; that skips whitespace, then reads characters into str until it encounters more whitespace expanding str as needed. char* works the same way except it reads charaiters into the the C style string untill it runs out of space, at which point it reads characters into whatever it would be most inconvenent to have characters read into and silently returns, smug in the knowlage that no_chars_per_page has been set to 1 and your next print job is going to waste a lot of paper.

    The other way to read into a std::string is getline(cin,str,'}'); This will read all characters into a string, including whitespace, until it encounters the terminating character, in this case it is '}', by default it's newline. It eats the terminator but does not add it to your string.

    In your case I think it's easyer just to parse from the stream. The simple but somewhat unsafe version is this:
    Code:
    void ez_parse(std::vector<int> &v, std::istream &is=std::cin) {
    	int n; 
    	char c;
    	is >> c; // get leading character
    	do {is >> n >> c; v.push_back(n);} while(c==',');
    }
    This will put int's into a vector from any input that cosists of any character followed by a number followed by either a non-comma or a comma and another number. {1} or {2, 3, -17 } both satisfy this, and thus work as does $3,2h. behavior is undefined for 5,4,,*. In fact on {3,,4} it will consume infinite memory. The more parinoid and safe version looks like.
    Code:
    bool parse(std::vector<int> &v, std::istream &is=std::cin) {
         int n;   
         char c=0;    // c must not == '{'
         is >> c;       // get leading '{', 
                           // if the stream is bad
                           // c is unchanged
         if(c != '{') return false;  // no leading {, or bad
                                              // stream, bail.
         do {
             is >> n >> c;  // read int,char skipping ws
             if(is.good()) v.push_back(n); 
             else return false;  // Doh! (vector unchanged)		
         } while(c==',');  // comma implies another int
    
             return c=='}';  // no comma, was it the end?
    }
    This version works only for input that is actually of the form "{ num [, num] }" if the return value is true then you can trust all the numbers appended to the vector. If the return value is false then the returned values are good, but possibly incomplete. Both take input from standard input by default, but you can read from a file with ifstream or even a string with istringstream if you want to.
    Code:
    std::vector<int> v;
    if(parse(v)) cout << "ok" << endl;
    std::istringstream iss("{5, 6, 7}");
    parse(v,iss);
    cout << '{';
    for(int j = 0;j<v.size()-1;++j) cout << v[j] << ", "
    cout << v.back() << '}' << endl;
    This will result in a vector of int's with whatever you entered followed by 5, 6, and 7. vectors work almost identically to arrays, the ways they are different mostly involve not sucking.



    (edit: tab dammage, last try)
    (edit: something like [eye] was parsed as begin italics, as good an example of how *not* to parse as this is, it's confusing)
    Last edited by grib; 03-26-2003 at 03:33 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Custom String class gives problem with another prog.
    By I BLcK I in forum C++ Programming
    Replies: 1
    Last Post: 12-18-2006, 03:40 AM
  2. Logical errors with seach function
    By Taka in forum C Programming
    Replies: 4
    Last Post: 09-18-2006, 05:20 AM
  3. Replies: 4
    Last Post: 03-03-2006, 02:11 AM
  4. the definition of a mathematical "average" or "mean"
    By DavidP in forum A Brief History of Cprogramming.com
    Replies: 7
    Last Post: 12-03-2002, 11:15 AM
  5. Again Character Count, Word Count and String Search
    By client in forum C Programming
    Replies: 2
    Last Post: 05-09-2002, 11:40 AM