0

Я только начал использовать строковый поток в первый раз, и мне нравится эта концепция, но мне трудно найти, где именно у меня выходит из диапазона в памяти, с моим струнным потоком функция.Проблема с пределами диапазона в памяти с использованием stringsteam

Что моя функция делает, так это взятие строки, например, «N02550 G3 X16.7379 Y51.7040 R0.0115« Это машинный код для машины с ЧПУ при моей работе. Я передаю строку в строковый поток, чтобы найти строки, которые рядом с ними имеют 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 в содержащие машинный код. Спасибо!

+0

Под «аварии» значит «кидает исключение»? Самый очевидный сценарий был бы, если 'at (0)' терпит неудачу, потому что строка пуста –

ответ

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 true. Таким образом, мы можем написать код, как:

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

Я выяснил, что вызвало проблему, это было связано с белыми линиями. Спасибо, что объяснили, почему и за совет, а не просто отправляйте ответ. Его трудно учиться с помощью только кода. Благодарим вас за совет, всегда ставя другое заявление, чтобы легче находить проблемы! –