Разделение строки в C++ с использованием разделителя (стандартный C++)
Я разбираю строку в C++ с использованием следующего кода:
using namespace std;
string parsed, input = "text to be parsed";
stringstream input_stringstream(input);
if (getline(input_stringstream, parsed, ' '))
{
// выполните некоторые операции.
}
Разбор с использованием одного символа в качестве разделителя работает нормально. Но что делать, если я хочу использовать строку в качестве разделителя?
Например, я хочу разбить строку:
scott>=tiger
с использованием >=
в качестве разделителя, чтобы получить scott
и tiger
. Как я могу это сделать?
5 ответ(ов)
Для разделителя строки
Если вам нужно разделить строку по строчному разделителю, вы можете использовать следующий код. Например, если у вас есть строка "adsf-+qwret-+nvfkbdsj-+orthdfjgh-+dfjrleih"
и вы хотите разделить её на основе разделителя "-+"
, то на выходе вы получите {"adsf", "qwret", "nvfkbdsj", "orthdfjgh", "dfjrleih"}
.
#include <iostream>
#include <sstream>
#include <vector>
// Функция для разделения строки по строковому разделителю
std::vector<std::string> split(std::string s, std::string delimiter) {
size_t pos_start = 0, pos_end, delim_len = delimiter.length();
std::string token;
std::vector<std::string> res;
while ((pos_end = s.find(delimiter, pos_start)) != std::string::npos) {
token = s.substr(pos_start, pos_end - pos_start);
pos_start = pos_end + delim_len;
res.push_back(token);
}
res.push_back(s.substr(pos_start));
return res;
}
int main() {
std::string str = "adsf-+qwret-+nvfkbdsj-+orthdfjgh-+dfjrleih";
std::string delimiter = "-+";
std::vector<std::string> v = split(str, delimiter);
for (auto i : v) std::cout << i << std::endl;
return 0;
}
Вывод
adsf
qwret
nvfkbdsj
orthdfjgh
dfjrleih
Для разделителя-символа
Если вам нужно разделить строку по разделителю-символу, вы можете использовать следующий код. Например, разделив строку "adsf+qwer+poui+fdgh"
с разделителем "+"
, вы получите {"adsf", "qwer", "poui", "fdgh"}
.
#include <iostream>
#include <sstream>
#include <vector>
// Функция для разделения строки по символу-разделителю
std::vector<std::string> split(const std::string &s, char delim) {
std::vector<std::string> result;
std::stringstream ss(s);
std::string item;
while (getline(ss, item, delim)) {
result.push_back(item);
}
return result;
}
int main() {
std::string str = "adsf+qwer+poui+fdgh";
std::vector<std::string> v = split(str, '+');
for (auto i : v) std::cout << i << std::endl;
return 0;
}
Вывод
adsf
qwer
poui
fdgh
Этот метод использует std::string::find
, не изменяя исходную строку, запоминая начало и конец предыдущего токена подстроки.
Пример кода:
#include <iostream>
#include <string>
int main()
{
std::string s = "scott>=tiger";
std::string delim = ">=";
auto start = 0U;
auto end = s.find(delim);
while (end != std::string::npos)
{
std::cout << s.substr(start, end - start) << std::endl;
start = end + delim.length();
end = s.find(delim, start);
}
std::cout << s.substr(start, end);
}
В этом примере мы инициализируем строку s
и разделитель delim
. Затем с помощью std::string::find
ищем позицию разделителя в строке s
. В цикле while
мы продолжаем искать разделитель, пока он не будет найден. Каждый найденный фрагмент строки выводится на экран. После того как разбиение завершено, выводится оставшаяся часть строки (если она есть) после последнего разделителя. Таким образом, метод позволяет разбить строку на подстроки, не изменяя исходную строку, что может быть полезно в различных сценариях.
Вы можете использовать следующую функцию для разбиения строки:
vector<string> split(const string& str, const string& delim)
{
vector<string> tokens;
size_t prev = 0, pos = 0;
do
{
pos = str.find(delim, prev);
if (pos == string::npos) pos = str.length();
string token = str.substr(prev, pos-prev);
if (!token.empty()) tokens.push_back(token);
prev = pos + delim.length();
}
while (pos < str.length() && prev < str.length());
return tokens;
}
Эта функция принимает на вход строку и разделитель, а затем возвращает вектор строк, полученных в результате разбиения. Она использует метод find
для поиска позиции разделителя в строке и substr
для извлечения подстрок. Обратите внимание, что пустые токены не добавляются в результирующий вектор.
В ответе уже указано решение, но выбранное решение использует функцию erase
, что может быть очень затратным по времени, особенно если строка очень большая (в мегабайтах). Поэтому я предлагаю использовать следующую функцию для разделения строки.
vector<string> split(const string& str, const string& delim)
{
vector<string> result;
size_t start = 0;
for (size_t found = str.find(delim); found != string::npos; found = str.find(delim, start))
{
result.emplace_back(str.begin() + start, str.begin() + found);
start = found + delim.size();
}
if (start != str.size())
result.emplace_back(str.begin() + start, str.end());
return result;
}
Эта функция работает без необходимости модифицировать исходную строку, что делает её более эффективной для больших строк. Она просто находит границы фрагментов и создает новые строки на их основе, избегая дорогостоящих операций удаления.
Этот код разделяет строки из текста и добавляет каждую в вектор.
Функция split
принимает char *phrase
— строку, которую нужно разделить, и string delimiter
— разделитель. Внутри функции создается вектор строк list
, в который будут добавляться полученные подстроки. Строка s
инициализируется значением phrase
. Затем, с помощью цикла while
, происходит поиск разделителя в строке s
. Если разделитель найден, отрезаем подстроку от начала до позиции разделителя и добавляем её в вектор. После этого удаляем обработанную часть строки с помощью erase
.
После завершения цикла в вектор добавляется оставшаяся часть строки (если таковая имеется).
Вот как вызывается эта функция:
vector<string> listFilesMax = split(buffer, "\n");
Здесь buffer
— это строка, содержащая текст, который необходимо разделить на строки, используя символ новой строки \n
в качестве разделителя. В результате вызова функции listFilesMax
будет содержать все строки из buffer
.
Как перебрать слова в строке?
Что такое Правило трёх?
Имеют ли круглые скобки после имени типа значение при использовании new?
Как разделить строку на массив в Bash?
Как удалить элемент из std::vector<> по индексу?