Мой код размещен ниже. Я хочу иметь возможность анализировать с помощью разделителей «()» и преобразовать строки в целые числа в 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. Я очень смущен и был бы признателен за любую помощь.
У меня была похожая проблема с необходимостью разбора нескольких разделителей, и я не мог найти хорошее решение где-либо, поэтому я просто сделал функцию.
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 в качестве разделителя, и вы можете выбрать, включать ли разделитель в возвращаемую строку.
Это не компилируется, потому что 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
,