Вы можете использовать std::getline(stream, stringToReadInto, delimeter).
Я лично использую свою собственную функцию, в которую встроены некоторые дополнительные функции, которая выглядит так:
StringList Seperate(const std::string &str, char divider, SeperationFlags seperationFlags, CharValidatorFunc whitespaceFunc)
{
return Seperate(str, CV_IS(divider), seperationFlags, whitespaceFunc);
}
StringList Seperate(const std::string &str, CharValidatorFunc isDividerFunc, SeperationFlags seperationFlags, CharValidatorFunc whitespaceFunc)
{
bool keepEmptySegments = (seperationFlags & String::KeepEmptySegments);
bool keepWhitespacePadding = (seperationFlags & String::KeepWhitespacePadding);
StringList stringList;
size_t startOfSegment = 0;
for(size_t pos = 0; pos < str.size(); pos++)
{
if(isDividerFunc(str[pos]))
{
//Grab the past segment.
std::string segment = str.substr(startOfSegment, (pos - startOfSegment));
if(!keepWhitespacePadding)
{
segment = String::RemovePadding(segment);
}
if(keepEmptySegments || !segment.empty())
{
stringList.push_back(segment);
}
//If we aren't keeping empty segments, speedily check for multiple seperators in a row.
if(!keepEmptySegments)
{
//Keep looping until we don't find a divider.
do
{
//Increment and mark this as the (potential) beginning of a new segment.
startOfSegment = ++pos;
//Check if we've reached the end of the string.
if(pos >= str.size())
{
break;
}
}
while(isDividerFunc(str[pos]));
}
else
{
//Mark the beginning of a new segment.
startOfSegment = (pos + 1);
}
}
}
//The final segment.
std::string lastSegment = str.substr(startOfSegment, (str.size() - startOfSegment));
if(keepEmptySegments || !lastSegment.empty())
{
stringList.push_back(lastSegment);
}
return stringList;
}
Где «StringList» — это определение типа std::vector, а CharValidatorFunc — это указатель на функцию (на самом деле, std::function для поддержки функтора и лямбда-выражения) для функции берет один символ и возвращает логическое значение. его можно использовать так:
StringList results = String::Seperate(" Meow meow , Green, \t\t\nblue\n \n, Kitties!", ',' /* delimeter */, DefaultFlags, is_whitespace);
И вернет результаты: {"Мяу-мяу", "Зеленый", "Синий", "Котята!"}
Сохранение внутреннего пробела «Мяу-мяу», но удаление пробелов, табуляций и новых строк, окружающих переменные, и разделение запятыми.
(CV_IS — это функторный объект для сопоставления определенного символа или определенного набора символов, взятых как строковый литерал. У меня также есть CV_AND и CV_OR для объединения функций проверки символов)
Для строкового литерала я бы просто бросил его в std::string(), а затем передал его функции, если только не требуется экстремальная производительность. Нарушение разделителей довольно легко сделать самостоятельно — вышеприведенная функция просто настроена в соответствии с типичным использованием и требованиями моих проектов, но не стесняйтесь изменять ее и требовать ее для себя.
person
Jamin Grey
schedule
20.03.2013