2

I am trying to write a short line that gets a string using getline and checks it for an int using stringstream. I am having trouble with how to check if the part of the string being checked is an int. I've looked up how to do this, but most seem to throw exceptions - I need it to keep going until it hits an int.

Later I will adjust to account for a string that doesn't contain any ints, but for now any ideas on how to get past this part?

(For now, I'm just inputting a test string rather than use getline each time.)

int main() {

    std::stringstream ss;
    std::string input = "a b c 4 e";

    ss.str("");
    ss.clear();

    ss << input;

    int found;
    std::string temp = "";

    while(!ss.eof()) {
            ss >> temp;
            // if temp not an int
                    ss >> temp; // keep iterating
            } else {
                    found = std::stoi(temp); // convert to int
            }
    }

    std::cout << found << std::endl;

    return 0;
}
Megan
  • 119
  • 1
  • 3
  • 13
  • possible duplicate of [stringstream string to int](http://stackoverflow.com/questions/5476616/stringstream-string-to-int) – Zach Saucier Feb 16 '15 at 03:51

3 Answers3

4

You could make of the validity of stringstream to int conversion:

int main() {

std::stringstream ss;
std::string input = "a b c 4 e";
ss << input;
int found;
std::string temp;

while(std::getline(ss, temp,' ')) {
    if(std::stringstream(temp)>>found)
    {
        std::cout<<found<<std::endl;
    }
}
return 0;
}
sajas
  • 1,599
  • 1
  • 17
  • 39
3

While your question states that you wish to

get a string using getline and checks it for an int

using stringstream, it's worth noting that you don't need stringstream at all. You only use stringstreams when you want to do parsing and rudimentary string conversions.

A better idea would be to use functions defined by std::string to find if the string contains numbers as follows:

#include <iostream>
#include <string>

int main() {
    std::string input = "a b c 4 e 9879";//I added some more extra characters to prove my point.
    std::string numbers = "0123456789";
    std::size_t found = input.find_first_of(numbers.c_str());

    while (found != std::string::npos) {
        std::cout << found << std::endl;
        found = input.find_first_of(numbers.c_str(), found+1);
    }

    return 0;
}

And then perform the conversions.

Why use this? Think about happens if you use a stringstream object on something like the following:

"abcdef123ghij"

which will simply be parsed and stored as a regular string.

jrd1
  • 10,358
  • 4
  • 34
  • 51
  • Any special why you dont intitalise `std::size_t found` to 0 in the beginning? – Ic3fr0g May 25 '16 at 10:50
  • 1
    @MayurH: Because [find_first_of](http://en.cppreference.com/w/cpp/string/basic_string/find_first_of) will always populate the value based on the existence of the character that we're looking for. In that context, initializing it to 0 (while pedantic) would be redundant (and arguably, meaningless). – jrd1 May 25 '16 at 15:39
  • 1
    Got it. Tried it out myself then realised. :) – Ic3fr0g May 25 '16 at 18:10
  • @MayurH: Sweet, glad to know! :) – jrd1 May 25 '16 at 20:08
  • this code returns index of where digits was found not the actual no – Umar Tahir Oct 24 '20 at 11:35
  • 1
    @UmarTahir: Thank you for your response. Your comment is accurate that this snippet obtains the index where the digits are found and not the actual number, which was done in consideration of the edge case I described in my answer - i.e. one should consider the case where the string isn't whitespace delimited. – jrd1 Oct 26 '20 at 15:28
0

Exceptions should not scary you.

int foundVal;
found = false;

while(!found || !ss.eof()) {
    try
    {
       foundVal = std::stoi(temp);  //try to convert
       found = true;
    }
    catch(std::exception& e)
    {
        ss >> temp; // keep iterating
    }
}

if(found)
    std::cout << foundVal << std::endl;
else
    std::cout << "No integers found" << std::endl;