создание функции разделения строк в переполнении стека

Возможный дубликат:
Разделение строки в C ++

Я пытаюсь создать функцию, которая имитирует поведение getline() функция, с возможностью использовать разделитель для разделения строки на токены.
Функция принимает 2 строки (вторая передается по ссылке) и char тип для разделителя. Он проходит по каждому символу первой строки, копирует его во вторую строку и останавливает цикл, когда достигает разделителя. Возвращается true если первая строка содержит больше символов после разделителя и false иначе. Позиция последнего символа сохраняется в статической переменной.
по какой-то причине программа входит в бесконечный цикл и ничего не выполняет:

const int LINE_SIZE = 160;
bool strSplit(string sFirst, string & sLast, char cDelim) {
static int iCount = 0;
for(int i = iCount; i < LINE_SIZE; i++) {
if(sFirst[i] != cDelim)
sLast[i-iCount] = sFirst[i];
else {
iCount = i+1;
return true;
}
}
return false;
}

Функция используется следующим образом:

while(strSplit(sLine, sToken, '|')) {
cout << sToken << endl;
}

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

3

Решение

Это не совсем то, что вы просили, но рассматривали ли вы std::istringstream а также std::getline?

// UNTESTED
std::istringstream iss(sLine);
while(std::getline(iss, sToken, '|')) {
std::cout << sToken << "\n";
}

РЕДАКТИРОВАТЬ:

Почему это входит в бесконечный цикл, и почему это не работает?

Мы не можем знать, вы не предоставили достаточно информации. Попробуйте создать SSCCE и опубликуйте это.

я Можно скажу вам, что следующая строка очень подозрительна:

       sLast[i-iCount] = sFirst[i];

Эта строка приведет к неопределенному поведению (включая, возможно, то, что вы видели) в любом из следующих условий:

  • i >= sFirst.size()
  • i-iCount >= sLast.size()
  • i-iCount < 0

Мне кажется вероятным, что все эти условия выполняются. Если переданная строка, например, короче 160 строк, или если iCount когда он станет больше, чем смещение первого разделителя, вы получите неопределенное поведение.

5

Другие решения

LINE_SIZE вероятно, больше, чем количество символов в string объект, поэтому код запускается из конца хранилища строки, и почти все может произойти.

Вместо того, чтобы кататься самостоятельно, string::find делает то, что вам нужно

std::string::size_type pos = 0;
std::string::size_type new_pos = sFirst.find('|', pos);

Призыв к find находит первое вхождение ‘|’ это в или после позиции «pos». Если это успешно, он возвращает индекс ‘|’ что он нашел. Если это не удается, он возвращает std::string::npos, Используйте его в цикле, и после каждого совпадения копируйте текст из [pos, new_pos) в целевую строку и обновляйте pos в new_pos + 1,

3

Вы уверены, что это strSplit() функция, которая не возвращает или это ваш вызывающий while цикл это бесконечно?

Не должен ли ваш цикл вызова быть чем-то вроде:

while(strSplit(sLine, sToken, '|')) {
cout << sToken << endl;
cin >> sLine >> endl;
}

— редактировать —

если значение sLine таков, что делает strSplit() чтобы вернуть истину, то while цикл становится бесконечным .. поэтому сделайте что-нибудь, чтобы изменить значение sLine для каждой итерации цикла, например положить в cin..

1

Проверь это

std::vector<std::string> spliString(const std::string &str,
const std::string &separator)
{
vector<string>      ret;
string::size_type   strLen = str.length();
char                *buff;
char                *pch;

buff = new char[strLen + 1];
buff[strLen] = '\0';
std::copy(str.begin(), str.end(), buff);

pch = strtok(buff, separator.c_str());
while(pch != NULL)
{
ret.push_back(string(pch));
pch = strtok(NULL, separator.c_str());
}

delete[] buff;

return ret;
}
0
По вопросам рекламы [email protected]