0

I just started using the stringstream for the first time and I love the concept, but I am having a hard time finding where exactly I am having an out of range in memory with my stringstream function.

What my function does is it takes in a string, for example, "N02550 G3 X16.7379 Y51.7040 R0.0115" This is machine code for a CNC machine at my job. I pass the string to a stringstream in order to find the strings that have a X, Z, Y next to them, these are coordinates. It then gets rid of the character at the beggining in order to save the float number to my struct "Coordinate"(there are 3 doubles, x, y, z).

When I run a text file that has this machine code with 33 lines, my program works. When I run it with machine code of 718 lines, it gets to 718, then crashes with out of range memory. Then another weird part is when I run machine code with 118,000 lines, it goes up to around 22,000 lines then crashes. So I'm having trouble figuring out why it is able to do that and whats causing the problem.

Here is the function:

   void getC(string& line, Coordinates& c)//coordinates holds 3 doubles, x, y, z
{
    //variables
    string holder;
    stringstream ss(line);

    while(ss)
    {
        ss >> holder;
        if(holder.at(0) == 'X')
        {
            holder.erase(0,1);//get rid the the character at the beggining
            stringstream sss(holder);
            sss >> c.x;
            sss.clear();
        }
        if(holder.at(0) == 'Y')
        {
            holder.erase(0,1);
            stringstream sss(holder);
            sss >> c.y;
            sss.clear();
        }
        if(holder.at(0) == 'Z')
        {
            holder.erase(0,1);
            stringstream sss(holder);
            sss >> c.z;
            sss.clear();
        }
        if(ss.eof()) // to get out of the ss stream
            break;

    }
    ss.clear();
}

If you want to see the whole application(the application is well documented) then ask or if you need the txt files containing the machine code. Thank you!

4

1 回答 1

2

尝试改变:

while(ss)
{
    ss >> holder;
    ...
    if(ss.eof()) // to get out of the ss stream
        break;
}

简单地说:

while(ss >> holder)
{
    ...
}

而且您可以摆脱对clear每个分支(X/Y/Z)的那些调用,因为它实际上并没有做任何事情,因为这sss是暂时的,而且您没有用它做更多的事情(没有必要在您的东西上设置标志) '将在之后丢弃)。我怀疑您的超出范围问题来自尝试访问失败holder.at(0)后。ss >> holder

您通常希望在读取令牌后立即检查输入失败,同时尝试输入和检查失败的一种方便方法是简单地检查是否ss >> token评估为真。所以我们可以编写如下代码:

if (ss >> token)
{
    ...
}
else
{
    // handle failure if necessary
}

我通常发现避免以这种方式编写代码比手动检查错误标志要容易得多。

作为简化版本:

void getC(string& line, Coordinates& c)
{
    stringstream ss(line);   
    for (string holder; ss >> holder; )
    {
        const char ch = holder.at(0);
        stringstream sss(holder.substr(1));
        if (ch == 'X')
            sss >> c.x;
        else if (ch == 'Y')
            sss >> c.y;
        else if (ch == 'Z')
            sss >> c.z;
    }
}
于 2015-06-02T05:38:20.580 回答