0

I'm working on a project for a data structures class. The goal is to use a tree to figure out if metaphorical dwarfs can pay their metaphorical taxes with metaphorical diamonds. Input is given as a string in the format "3 1 2 3 3 1 2 3" which implies 3 diamonds of value 1 2 3 and 3 taxes cost of 1 2 3.

The issue I am having does not descend from the implementation of the tree but dealing with parsing the input into a way that I can insert it into the tree and such, specifically: When I input values in the code directly when testing it gives the correct output, but when using cin the output run into a few problems.

With the following code:

string str;
str = "5 1 2 3 4 5 5 1 2 3 4 5";


str.erase(remove_if(str.begin(), str.end(), ::isspace), str.end());
char ch[str.size()];
strcpy(ch, str.c_str());

int numDiamonds = ch[0] - '0';
cout<<numDiamonds<<" diamonds"<<endl;

int counter = 1;

for(int i = 1; i < numDiamonds+1; ++i){
    int out = ch[i] - '0';
    cout<<out;
    cout<<" ";
    ++counter;
}

cout<<endl;

int numTaxes = ch[numDiamonds+1] - '0';

cout<<numTaxes<<" taxes"<<endl;
for(int i = counter+1; i < str.size(); ++i){
    int out = ch[i] - '0';
    cout<<out;
    cout<<" ";
}
cout<<endl;
}

my output appear correct, and as follows:

5 diamonds
1 2 3 4 5
5 taxes
1 2 3 4 5

but when I change "str = 5 1..." to "cin >> str" my output appears jumbled and is the following.

5 diamonds
-48 -48 -48 -48 -48
-20 taxes

1 diamonds
-48
-48 taxes

2 diamonds
-48 -48
-48 taxes

3 diamonds
-48 -48 -48
-48 taxes

4 diamonds
-48 -48 -48 -48
-48 taxes

5 diamonds
-48 -48 -48 -48 -48
-20 taxes

5 diamonds
-48 -48 -48 -48 -48
-20 taxes

1 diamonds
-48
-48 taxes

2 diamonds
-48 -48
-48 taxes

3 diamonds
-48 -48 -48
-48 taxes

4 diamonds
-48 -48 -48 -48
-48 taxes

5 diamonds
-48 -48 -48 -48 -48
-20 taxes

No amount of googling has helped solve my problem, so I turn you guys. Is there an explanation as to why cin into a string has different behavior than defining the string in the code?

Thanks!

Suki
  • 111
  • 2
  • 9

3 Answers3

3

That is because input ends when it encounters a space, that is it reads only the first number. Use cin.getline() instead.

The exact input line would be: getline(cin, str), because you are using std::string otherwise, the cin.getline() would have done the job too.

Navneeth G
  • 7,255
  • 1
  • 15
  • 18
1

Try using std::getline(cin, str).

rasmus
  • 3,136
  • 17
  • 22
-1

cin just takes up to the next whitespace character.

You could use cin.getline, but a better alternative, seeing what you're using it for, is to loop a cin for each integer.

So you can do:

vector<int> input;

int x;
while (cin.good()) {
    cin >> x;
    input.push_back(x);
}

cin.good() just checks if the stream is still... well, good. If there's a problem with the stream (for example, if you get to the end of the stream), it returns 0. It's a good way to retrieve items from stdin if you know its format, and it's generally how you read from stdin for ICPC/topcoder problems. Makes things a lot simpler, wouldn't you agree? :)

Pochi
  • 2,026
  • 1
  • 15
  • 11
  • 1
    Reading an input stream this way is a bad practice. [Please read this.](http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong) – Blastfurnace Feb 10 '12 at 07:40
  • If you know the format of your input, it's great. Also, fixed. – Pochi Feb 11 '12 at 09:32