为什么不通过std :: cin复制并粘贴到控制台读取产生与从std :: ifstream读取相同的结果?

时间:2014-04-24 05:37:42

标签: c++ eclipse stl eclipse-cdt

我在linux上使用eclipse IDE。 我遇到的问题是当我将输入文件复制并粘贴到控制台时,我使用std::cin;复制并粘贴std::cin时得到的答案不正确,对于小例子工作正常,但是对于较大的例子则失败了。

为什么通过std::cin读取的复制和粘贴不起作用? 如何通过std::cin进行复制和粘贴工作?

当我通过std::ifstream打开并阅读输入文件时,一切正常。

这是我正在运行的旧版Google代码堵塞的问题。 https://code.google.com/codejam/contest/351101/dashboard#s=p0

这两者都很常见:

#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;
}

这是我的主std::cin版本,当我复制并粘贴小输入时有效,但在复制和粘贴大输入时失败:

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;
}

以下是我从剪切和粘贴中得到的错误的大输出:

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

这是一个直接读取输入文件而不是剪切和粘贴的版本:

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;
}

1 个答案:

答案 0 :(得分:0)

在您的控制台中复制/粘贴文本与您的程序几乎没有关系,这由shell处理,它会将粘贴的数据传递给您的程序(因此,输入或粘贴文本,就像您的一样)程序是关注的。)


但是,您的代码存在问题。

  • 首先,它有未定义的行为:当你执行delete &testArr[i];时,你在堆栈分配的对象上调用delete,这是不允许的(并且是不必要的) 。您只应在delete ed对象上调用new

  • 其次,在你的test构造函数you should not do while (!iss.eof())中,你可能正在为最后一次迭代读取垃圾。

你应该这样做:

while (iss >> temp)
{
    itemList.push_back(temp);
}