0

I am trying to split specific string with couple of different ways. The example of my input is (-5,3,0,1,-2).

And this is my first code,

// code 1
string s = "(-5,3,0,1,-2)";
int j = 0;
int * temp = new int[s.length()];
for (int i = 0; i < s.length(); i++) {
    if (s[i] != '(' && s[i] != ',' && s[i] != ')') {
        temp[j++] = (s[i]-'0');
    }
}

code 1 works well except, it converts - sign to ascii value(45) not negative int value.

//code2
char *first = _strdup(s.c_str());
char * temp2 = NULL;
char *temp = strtok_s(first, "(,)", &temp2);
/* Expected output is
temp[0] = -5
temp[1] = 3
temp[2] = 0
temp[3] = 1
temp[4] = -2
*/

However middle of debugging, temp contains ascii value, not string value. Also not sure code2 is correctly working.

Thanks in advances!

jayko03
  • 2,329
  • 7
  • 28
  • 51
  • What exactly is your question? And yes, if you interpret `'-'` as `char`, you will be looking at its ASCII value. Check out [strtol()](http://en.cppreference.com/w/c/string/byte/strtol). – DevSolar Nov 20 '17 at 07:38
  • Have you considered to use one of the approaches given [here](https://stackoverflow.com/q/53849/1025391) or [here](https://stackoverflow.com/q/236129/1025391) ? – moooeeeep Nov 20 '17 at 07:40
  • And all other things aside, this is very much C, and very little C++. Going the iostreams route, you'd get results much easier... – DevSolar Nov 20 '17 at 07:40

5 Answers5

1

You need a proper string to int conversion. Use std::stoi. I used the boost tokenizer. It is very handy for your case.

#include <string>
#include <boost/tokenizer.hpp>
#include <vector>

using namespace std;
using namespace boost;

int main() {
    vector<int> intList
    string text = "(-5,3,0,1,-2)";
    char_separator<char> sep(",");
    tokenizer<char_separator<char>> tokens(text, sep);
    for (const auto& t : tokens) 
          intList.push_back(std::stoi(t));

}

PS. you forgot the delete for you new. Please use a proper container (e.g. std::vector).

schorsch312
  • 5,553
  • 5
  • 28
  • 57
  • It looks simple and easy, but my compiler cannot open boost/tokenizer.hpp – jayko03 Nov 20 '17 at 20:44
  • @jaykodeveloper: Well, you need to have the Boost libraries and headers installed, obviously... – DevSolar Nov 20 '17 at 23:45
  • @DevSolar Thanks. I just want to use standard libraries. – jayko03 Nov 21 '17 at 02:32
  • @jaykodedeveloper Why dont you want to usw boost? – schorsch312 Nov 21 '17 at 05:37
  • @jaykodeveloper: I understand the sentiment. On the one hand, Boost *is* a handful, especially on Windows where there are no precompiled binaries to be had from the developers themselves. However, Boost is as close to "standard" as you can get. In a way, Boost is the "staging area" for inclusion in `std::`. – DevSolar Nov 21 '17 at 06:28
  • @schorsch312 @DevSolar it is related to project and I am not not sure grader has `boost`. But I read its documentation and it usage. It seems very useful for c++ beginner. Thanks – jayko03 Nov 21 '17 at 07:27
  • @jaykodeveloper: Note that a great many of the Boost libraries are "header only", i.e. there is no lib binary to link against, and as such no need to install anything extra on the target machine. (Check [here](http://www.boost.org/doc/libs/release/more/getting_started/unix-variants.html) for details.) If this is homework, of course you should check with your instructor if it is acceptable for you to use Boost. – DevSolar Nov 21 '17 at 07:32
0

Use istrstream::get method. You can avoid the open and close braces by replacing those.

void _parse_(istrstream &str,string &strText, char ch = ',')
{
    char chText[MAX_PATH];
    str.get(chText, MAX_PATH,ch);
    str.get(ch);
    strText = chText;
}

string s = "(-5,3,0,1,-2)";
istrstream inputStream(s);
string sTemp;

//Replace here the open and close braces.

do
{
   _parse_(inputStream, sTemp,',');
   //Your value in sTemp

}while(!sTemp.empty())
0

If you need use c++ without any library, you can use flowing code:

#include <string>
#include <vector>

using namespace std;
int main()
{
    string s = "(-5 2,3 0 1, 0 , 1 , -21 0 )";
    int location = 0;
    vector<int> array;
    string sub;
    while (location <= s.length())
    {
        if ((s[location] >= 48 && s[location] <= 57) || s[location] == 45 || s[location] == 32)
        {
            if (s[location] != 32)
            {
                sub += s[location];
            }
        }
        else
        {
            if (sub.length() != 0)
            {
                std::string::size_type sz;
                int num = stoi(sub, &sz);
                array.push_back(num);
            }
            sub.clear();
        }
        location++;
    }
    return 0;
}
mohammad madani
  • 868
  • 9
  • 18
  • It works well, except target string contains space. then it does not contain values after space. Do you have other suggestion? – jayko03 Nov 21 '17 at 03:06
  • Once it has space, it just existed program. `The program has exited with code 0`. I used same `"(-5 2,3 0 1, 0 , 1 , -21 0 )"` this as well. – jayko03 Nov 21 '17 at 06:55
  • I run my code with your entry on last comment.it's work well.what is your problem? – mohammad madani Nov 21 '17 at 07:38
0
#include <sstream>
#include <iomanip>

using namespace std;

const string INTEGER_CHARS {"0123456789+-"};

vector<int> readIntFromString(const string src) {
    const char stopFlag{'\0'};
    const string str {src + stopFlag};

    vector<int> numbers;

    stringstream ss(str);
    int tmp;
    for(char nextChar = ss.peek(); nextChar != stopFlag; nextChar = ss.peek()) {
        if (INTEGER_CHARS.find(nextChar) != string::npos) {
            ss >> setbase(0) >> tmp;
            numbers.push_back(tmp);
        } else {
            ss.ignore();
        }
    }
    return numbers;
}

setbase(0): make >> operator to recognize other based numbers, e.g. 0b01, 070, 0xF

ss.ignore(): skip the char we don't care

QooBee
  • 21
  • 5
-1

You can use the following,

string s = "(-5,3,0,1,-2)";
int j = 0;
string temp;
std::vector<int> values;
for (int i = 0; i < s.length(); i++) 
{
    if (s[i] != '(' && s[i] != ')') 
    {
        while (s[i] != ',' && s[i] != ')')
        {
            temp += s[i];
            ++i;
        }
        values.push_back(std::atoi(temp.c_str()));
        temp.clear();
    }
}