0

I'm using eclipse IDE on linux. The problem I have is when I copy and paste the input file into the console I get incorrect answers when using std::cin; copy and paste with std::cin worked fine for the small example, but failed with the larger one.

Why does the copy and paste being read through std::cin not work? How would I get the copy and paste through std::cin to work?

Everything functions correctly when I open and read the input file through std::ifstream.

This is a problem from an old google code jam that I was running through. https://code.google.com/codejam/contest/351101/dashboard#s=p0

This is common to both:

#include <iostream>
#include <ios>
#include <string>
#include <vector>
#include <sstream>
#include <fstream>
#include <limits>

class test {
public:
    int credit;
    int numListItems;
    std::vector<int> itemList;
    int result[2];

    test(int c, int i, std::string s)
    {
        std::istringstream iss(s);
        int temp;
        credit = c;
        numListItems = i;
        itemList.clear();
        while (!iss.eof())
        {
            iss >> temp;
            itemList.push_back(temp);
        }

    }

    void process()
    {
        for (int i = 0; i < this->numListItems; ++i)
            for (int j = i+1; j < this->numListItems; ++j)
            {
                if ((this->itemList[i] + this->itemList[j]) == this->credit)
                {
                    this->result[0]=i;
                    this->result[1]=j;
                    i=this->numListItems+1;
                    break;
                }
            }
    }

private:
};

std::ostream& operator<<(std::ostream& os, const test& obj)
{
    os << obj.result[0]+1 << " " << obj.result[1]+1;
    return os;
}

Here is my main std::cin version that works when I copy and paste the small input, but fails when I copy and paste the large input:

int main(int argc, char* argv[]) {

    std::vector<test> testArr;
    std::string listLine, tempStr;
    int numCases,c,nItems;

    std::cin >> numCases;
    for (int i = 0; i < numCases; ++i)
    {
        std::cin >> c;
        std::cin >> nItems;
        listLine="";
        for (int j =0; j < nItems; j++)
        {
            std::cin >> tempStr;
            if (j < (nItems-1))
                listLine = listLine + tempStr + " ";
            else
            {
                listLine = listLine +tempStr;
            }
        }
        testArr.push_back(test(c,nItems,listLine));
    }

    for (int i = 0; i < numCases; ++i)
    {
        testArr[i].process();
        std::cout << "Case #" << i+1 << ": "
                    << testArr[i] << std::endl;
    }

    for (int i = 0; i < numCases; ++i)
    {
        delete &testArr[i];
    }

    return 0;
}

Here is the incorrect large output I get from cut and paste:

Case #1: 2 3
Case #2: 1 4
Case #3: 4 5
Case #4: 29 46
Case #5: 11 56
Case #6: 84 240
Case #7: 413 584
Case #8: 28 80
Case #9: 381 634
Case #10: 17 18
Case #11: 8 447
Case #12: 402 619
Case #13: 43 61
Case #14: 2 27
Case #15: 18 69
Case #16: 3 85
Case #17: 7 173
Case #18: 4 555
Case #19: 4 476
Case #20: 9 303
Case #21: 5 70
Case #22: 16 869
Case #23: 3 1
Case #24: 3 1
Case #25: 156 327
Case #26: 3 198
Case #27: 1 303
Case #28: 24 36
Case #29: 1 79
Case #30: 1 356
Case #31: 1 3
Case #32: 4 319
Case #33: 10 41
Case #34: 16 335
Case #35: 8 205
Case #36: 98 314
Case #37: 28 57
Case #38: 1 396
Case #39: 12 30
Case #40: 1 57
Case #41: 15 75
Case #42: 33 57
Case #43: 3 1
Case #44: 2 152
Case #45: 9 68
Case #46: 8 122
Case #47: 17 48
Case #48: 7 11
Case #49: 1 76
Case #50: 27 278

And here is a version that works by reading the input file directly instead of cut and paste:

int main(int argc, char* argv[]) {

    std::vector<test> testArr;
    std::string listLine, tempStr;
    int numCases, c, nItems;

    std::ifstream myFile("./A-large-practice.in");

    if (myFile.is_open())
    {
        myFile >> numCases;
        for (int i = 0; i < numCases; ++i)
        {
            myFile >> c;
            myFile >> nItems;

            listLine="";
            for (int j =0; j < nItems; j++)
            {
                myFile >> tempStr;
                if (j < (nItems-1))
                    listLine = listLine + tempStr + " ";
                else
                    listLine = listLine +tempStr;

            }
            testArr.push_back(test(c,nItems,listLine));
        }
        myFile.close();
    }
    else
    {
        std::cout << "unable to open file!" << std::endl;
    }


    for (int i = 0; i < numCases; ++i) {
        testArr[i].process();
        std::cout << "Case #" << i+1 << ": "
                    << testArr[i] << std::endl;
    }

    return 0;
}
quantdev
  • 22,595
  • 5
  • 47
  • 84
PopcornKing
  • 1,210
  • 3
  • 15
  • 21

1 Answers1

0

Copy / pasting text in your console has little to do with your program, this is handled by the shell, which will pass the pasted data to your program (so, typing or pasting the text, is the same as far as your program is concerned).


However, there are issues with your code.

  • First, it has undefined behavior : when you do delete &testArr[i]; , you are calling delete on stack allocated objects, this is not allowed (and unnecessary). You should only call delete on newed objects.

  • Second, in your test constructor, you should not do while (!iss.eof()), you are probably reading garbage for last iteration.

You should do :

while (iss >> temp)
{
    itemList.push_back(temp);
} 
Community
  • 1
  • 1
quantdev
  • 22,595
  • 5
  • 47
  • 84