Я только начал использовать струнный поток в первый раз, и мне нравится эта концепция, но мне трудно найти, где именно у меня выходит за пределы диапазона памяти в моей функции струнного потока.
Что моя функция делает, так это принимает в строке, например, «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-файлы, содержащие машинный код. Спасибо!
Попробуйте изменить:
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;
}
}