C ++ peek()没有看到换行符

时间:2013-04-16 04:23:58

标签: c++

我在阅读文件中的输入方面遇到了一些麻烦,我确实不应该在家庭作业上阅读。我在之前的一个赋值中使用了非常相似的代码(唯一改变的是值被推到的地方)。我收到了一个带有以下输入的文本文件:

10
3 6 4 9 0 7 8
8 5 3 7 3 4 -2
5 10 2 8 1 4 1
2 6 -3 1 3 7 1
1 10 -1 2 2 4 -2
10 9 -3 1 3 7 2 5 1
7 3 0 10 1 2 1 8 2
9 6 6 3 4 10 7
4 8 5 1 9 5 6
6 2 4 3 0 9 0

第一行是上图的顶点数。在每一行之后,第一个数字是这个顶点,下一个数字是它连接到哪个顶点,后面的数字是该边缘的权重。该线重复顶点,重量直到线的末端(即,第一条线用于顶点3,它的边缘为6,重量为4,边缘为9,重量为0,等等)。我使用1d向量来表示使用行主要表示法的矩阵。我遇到的问题是我的行变量似乎根本没有更新。目前,我从while循环的最后一行获得以下输出,实际上将数据插入到向量中。

3:  6: 4
3:  9: 0
3:  7: 8
3:  8: 5
3:  3: 7
3:  3: 4
3:  -2: 5
3:  10: 2
3:  8: 1
3:  4: 1
3:  2: 6
3:  -3: 1
3:  3: 7
3:  1: 1
3:  10: -1
3:  2: 2
3:  4: -2
3:  10: 9
3:  -3: 1
3:  3: 7
3:  2: 5
3:  1: 7
3:  3: 0
3:  10: 1
3:  2: 1
3:  8: 2
3:  9: 6
3:  6: 3
3:  4: 10
3:  7: 4
3:  8: 5
3:  1: 9
3:  5: 6
3:  6: 2
3:  4: 3
3:  0: 9
3:  0: 9

我的行变量似乎被卡住了3,就像input.peek()一样,因为while循环的条件永远不会看到新行字符。真正令人困惑的部分是,在类似的任务中,这段代码可以很好地迭代输入文件并填充应该去的地方。我很难过,所以如果有人能指出我正确的方向,我会非常感激。如果我过于冗长,我会提前道歉。

我的代码如下。

if(input.is_open()) // making sure the input is open
{
    input >> nodeCount; //Grabbing the number of nodes from the first value of the file

    for(int i = 1; i < nodeCount*nodeCount; i++)
    {
        edgeList.push_back(graphNode());
        edgeList[i].value = infinity;
        edgeList[i].isInfinity = true;
        edgeList[i].pred = -1;
    }

    //Putting data from the file into the vector array
    while(!input.eof())
    {
        input >> row; //For each cycle through the list, we grab the first number on the line to get which x value (start vertex) we're working with
        while(input.peek() != '\n' && !input.eof())
        {
            input >> col;
            input >> edgeList[((row-1)*nodeCount)+(col-1)].value;
            edgeList[((row-1)*nodeCount)+(col-1)].isInfinity = false;
            edgeList[((row-1)*nodeCount)+(col-1)].pred = row;
            cout << row << ": " << " " << col << ": " << edgeList[((row-1)*nodeCount)+(col-1)].value << endl;
        }

    }
    input.close(); //Closing our input file since we don't need it anymore
}

2 个答案:

答案 0 :(得分:2)

通过查看您吐出的数字,很明显这个条件在文件结束之前永远不会评估为假:

input.peek() != '\n' && !input.eof()

我的问题是 - 你使用的是windows风格,unix风格还是mac风格的行结尾?是否有更好的方法可以找出哪些行不会依赖假设它们采用某个ASCII值?

答案 1 :(得分:0)

读取一行的最佳方法是实际读取该行。

std::string  line;
std::getline(input, line);

然后,您可以解析该行之外的数字。

std::stringstream linestream(line);
int node;
linestream >> node;

int dst, weight;
while(linestream >> dst >> weight)
{
    // Do Stuff
}

你应该小心:

while(!input.eof())

这是一种反模式。你必须要小心,好像流进入错误状态,测试将永远不会成为真,因此可能会让你陷入无限循环。

所以你的代码应该是这样的:

int linesToRead;
input >> linesToRead;    

std::string  line;
for(;std::getline(input, line) && linesToRead;--linesToRead)
{
    // If there is a chance of an empty line
    // you may want to check here.

    std::stringstream linestream(line);
    int node;
    linestream >> node;

    int dst, weight;
    while(linestream >> dst >> weight)
    {
        // Do Stuff
    }
}

手动关闭文件不是好习惯。

input.close();

可能会将流设置为出错。如果你调用close()并抛出会发生什么?即使您处于正常模式,它只是在close()上生成错误。你打算做什么?最好让析构函数关闭文件并为您处理错误条件。见here