Я очень запутался в том, как анализировать несколько разделителей, используя getline и strtok в Stack Overflow

Мой код размещен ниже. Я хочу иметь возможность анализировать с помощью разделителей «()» и преобразовать строки в целые числа в cpp.

while(getline(fin, line))
{
x  = atoi((strtok(line.c_str(),'(,)'));
xx = atoi((strtok(NULL,"(),"));
xxx = atoi((strtok(NULL,"(),")));
cout << x << "    " << xx << "    " << xxx << "\n";
}

но по какой-то причине я получаю следующие ошибки

GraphTest.cpp: 134: ошибка: неверное преобразование из «const char *» в «char *»

GraphTest.cpp: 134: ошибка: инициализация аргумента 1 из «char * strtok (char *, const char *)»

.C_str должен преобразовать мою строку в строку типа c, что позволит мне использовать функции atoi и strtok. Я очень смущен и был бы признателен за любую помощь.

1

Решение

У меня была похожая проблема с необходимостью разбора нескольких разделителей, и я не мог найти хорошее решение где-либо, поэтому я просто сделал функцию.

string getlineMultDelimiter(istream &is, string dlm, bool includeDelimiter)
{
string str;
char c;
bool found = false;

while (!found && is)
{
for (size_t i = 0; i < dlm.length() && !found; ++i)
found = dlm[i] == is.peek();

if (!found || includeDelimiter)
{
is.get(c);
str += c;
}
}
return str;
}

Он будет использовать все символы в строке dlm в качестве разделителя, и вы можете выбрать, включать ли разделитель в возвращаемую строку.

0

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

Это не компилируется, потому что c_str() возвращает const char*, это должен быть постоянный указатель на неизменяемый внутренний string буфер. С другой стороны strtok() принимает char* потому что он изменяет свою входную строку.

Теперь у вас есть два варианта: получить строку C, пригодную для использования из strtok() или переписать все, чтобы быть C ++.

Создайте новую модифицируемую строку C из строки C ++:

char* modifiableLine = strdup(line.c_str());

x  = atoi((strtok(modifiableLine, "(,)"));
// Other processing

free(modifiableLine);

Вы можете сделать это, если вам нужно сохранить большой количество кода C, заключенного в функцию / класс C ++. Лучшее решение — использовать то, что предлагает стандартная библиотека C ++ (также atoi() Функция C, если C ++ 11). Давайте сначала напишем вспомогательную функцию:

int readNextInt(istringstream& is, const string& delimiters) {
string token;

if (getline(is, token, delimiters))
return stoi(token);

return 0; // End of stream?
}

Используется так:

istringstream is(line)
x = readNextInt(is, "(),");
xx = readNextInt(is, "(),");
xxx = readNextInt(is, "(),");

Обратите внимание, что стандартная функция C ++ getline() не принимает string для параметра разделителей, но один char только тогда вы должны написать свою собственную перегруженную версию. Посмотрите на эта почта для хорошей и хорошей возможной реализации (вы также можете просто заменить getline() с is >> token после is.imbue()см. приведенный пример).

Ну … если вы уже используете Boost, вы можете просто использовать boost::tokenizer,

0

По вопросам рекламы [email protected]