-1

So I am using stringstream in a function in c++ to take the numbers from a string, and then return the numbers to an array in main, but for some reason, they always return as 0 instead of the actual numbers. Code is below, does anyone know how to fix this?

int main()
{
for(int i = 0; i < userInput.length(); i++)
{
...
else
{
chemNumbers[i] = extractIntegerWords(userInput);
cout << chemNumbers[i] << endl;

}

}
int extractIntegerWords(string str)
{
    stringstream ss;
    int num = 0;

    ss << str;

    /* Running loop till the end of the stream */
    string temp;
    int found;
    if(!ss.eof())
    {

        ss >> temp;
        if (stringstream(temp) >> found)
        {
           num = found;
        }
        temp = "";

    }
    return found;
}

The original if statement doesn't pertain to the function only what is seen in the else statement, which is in main

  • what is input, output and expected output? not clear why you use 2 stringstreams. Please dont include "Some more irrelevant code here" in the example, if some code is not relevant then remove it completely, but make sure the example still compiles and reproduces the error (see also [mcve]) – 463035818_is_not_an_ai Nov 20 '19 at 09:15
  • as written this cannot compile because you define a function inside `main`. this is not allowed – 463035818_is_not_an_ai Nov 20 '19 at 09:16
  • The input is user input and should take the form of some sort of chemical compound like C6H12O6 and I want to take out each number and put it into a separate value of the array chemNumbers[i], I forgot to include that the if else is in a for loop. – I'mbadatCS Nov 20 '19 at 09:18
  • you can [edit](https://stackoverflow.com/posts/58950584/edit) the question to include the missing information and fix the code – 463035818_is_not_an_ai Nov 20 '19 at 09:19
  • Sorry fixed it, it does compile, it is declared outside of main i just messed up on the brackets, it just always prints out 0 for whatever is in chemNumbers[i]. – I'mbadatCS Nov 20 '19 at 09:20
  • please add input, output and expected output to the question – 463035818_is_not_an_ai Nov 20 '19 at 09:20
  • Forget for a moment about string steam. You are not assigning the found strings to the global array. You are assigning only a single value. For setting steam numbers parsing you can look up other stack overflow examples like this https://stackoverflow.com/questions/36705943/string-stream-in-c-to-parse-string-of-words-numbers – Dr Phil Nov 20 '19 at 09:21
  • ...you removed most code, but now the quesitons isnt in synch anymore. "The original if statement doesn't pertain to the function only what is seen in the else statement, which is in main" what? – 463035818_is_not_an_ai Nov 20 '19 at 09:21
  • Added just a debug line [here](https://ideone.com/bgly3t). You should better understand why you don't have expected result (`C6H12O6` **is** a string). – Jarod42 Nov 20 '19 at 09:26

3 Answers3

0

I add option for array instead vector for @I'mbadatCS

#include <vector>
#include <string>
#include <sstream>
#include <iostream>

using namespace std;

vector<int> extractIntegerWords(const string& _str)
//for array option: void extractIntegerWords(const string& _str, int* numArr)
{
    stringstream ss;
    ss << _str;    
    vector<int> vec;

    string temp;
    int found;
    //for array option: int idx = 0;

    while(!ss.eof())
    {
        ss >> temp;
        if (stringstream(temp) >> found)
        {
           vec.push_back(found);
           //for array option:numArr[idx++] = found;
        }
        temp = ""; 
    }

    return vec;
//for array option: return;
}

int main()
{
    string s = "bla 66 bla 9999 !"
    vector<int> res = extractIntegerWords(s);
    for (int i = 0; i < res.size(); ++i)
    {
        cout << res[i] << ", " << endl;
    }

}

a few comments:

  1. const string& in input argument, not string. you don't want harm your source data
  2. you need a loop not "if" (like ths the operation will run just one time)
  3. where your array??
  4. in C++ prefer use vector and not array
gil
  • 1
  • 3
  • Hi man this looks good, I just am not sure how vectors work just yet as I am still relatively new to C++, how would I call that in main? – I'mbadatCS Nov 20 '19 at 09:44
  • in basicly, vector is array with auto managment. you can replace the "vector" in int[10] (let's assume you know you have max 10 numbers, if you haven't any idea about it and there is option is a big amount you need dynamic allocoation). I add it to the answare – gil Nov 20 '19 at 10:21
0

This is off the top of my head and I don't have much time to test it, but this should put you in the right direction:

#include <iostream>
#include <string>
#include <sstream>
#include <vector>

using std::cout; 
using std::endl;
using std::istringstream;
using std::string;
using std::vector;

inline bool tryGetInt(const string& str, string& out) { istringstream sStream(str); return !(sStream >> out).fail(); } /*!< Tries to parse a string to int. */

void splitString(const string &str, const string &delimiters, vector<string> &tokens) {
    // Skip delimiters at beginning.
    string::size_type lastPos = str.find_first_not_of(delimiters, 0);
    // Find first "non-delimiter".
    string::size_type pos = str.find_first_of(delimiters, lastPos);

    while (string::npos != pos || string::npos != lastPos) {
        // Found a token, add it to the vector.
        tokens.push_back(str.substr(lastPos, pos - lastPos));
        // Skip delimiters.  Note the "not_of"
        lastPos = str.find_first_not_of(delimiters, pos);
        // Find next "non-delimiter"
        pos = str.find_first_of(delimiters, lastPos);
    }
}

int32_t main(int argCount, char* argValues[]) {
    for (int32_t i = 0; i < argCount; i++) {
        cout << "Found argument " << argValues[i] << endl;
        auto foundIntegers = getIntegerFromString(string(argValues[i]));

        // Do whatever
    }

    return 0;
}

vector<int64_t> getIntegerFromString(string formula) {
    vector<int64_t> foundInts;
    string temp;

    if (tryGetInt(formula, temp)) {
        vector<string> intsAsStrings;
        splitString(temp, " ", intsAsStrings);
        for (auto item : intsAsStrings) {
            foundInts.push_back(stol(item));
        }
    }

    return foundInts;
}
SimonC
  • 1,547
  • 1
  • 19
  • 43
0

Regular expression might help:

std::vector<std::pair<std::string, std::size_t>> Extract(const std::string& s)
{
    std::vector<std::pair<std::string, std::size_t>> res;
    const std::regex reg{R"(([a-zA-Z]+)(\d*))"};

    for (auto it = std::sregex_iterator(s.begin(), s.end(), reg);
         it != std::sregex_iterator();
         ++it)
    {
        auto m = *it;
        res.push_back({m[1], m[2].length() == 0 ? 1 : std::stoi(m[2])});
    }
    return res;
}

int main()
{
    for (auto p : Extract("C6H12O6")) {
        std::cout << p.first << ": " << p.second << std::endl;
    }
}

Demo

Jarod42
  • 203,559
  • 14
  • 181
  • 302