使用stringsteam

时间:2015-06-02 05:30:58

标签: c++ stringstream istringstream indexoutofrangeexception

我刚开始第一次使用stringstream而且我喜欢这个概念,但是我很难通过我的stringstream函数找到我在内存中超出范围的地方。

我的功能是什么,它需要一个字符串,例如,“N02550 G3 X16.7379 Y51.7040 R0.0115”这是我工作的CNC机床的机器代码。我将字符串传递给字符串流,以便找到旁边有X,Z,Y的字符串,这些是坐标。然后它会在开始时删除字符,以便将浮点数保存到我的结构“坐标”(有3个双精度数,x,y,z)。

当我运行一个包含33行的机器代码的文本文件时,我的程序可以工作。当我使用718行的机器代码运行它时,它会达到718,然后超出范围内存而崩溃。然后另一个奇怪的部分是当我运行118,000行的机器代码时,它会上升到大约22,000行然后崩溃。因此,我无法弄清楚为什么能够做到这一点以及导致问题的原因。

这是功能:

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

如果您想查看整个应用程序(应用程序已有详细记录),请询问或是否需要包含机器代码的txt文件。谢谢!

1 个答案:

答案 0 :(得分:2)

尝试更改:

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

简单地说:

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

你可以在每个分支(X / Y / Z)中删除对clear的调用,因为它不会真正做任何事情,因为sss是暂时的,而你#&# 39;不要再用它做任何事情(没有点设置你将要在之后丢弃的东西上的标记)。我怀疑在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;
    }
}