10

Как обрезать std::string?

11

Я в данный момент использую следующий код для удаления пробелов и символов новой строки с правой стороны всех std::string в своих программах:

std::string s;
s.erase(s.find_last_not_of(" \n\r\t")+1);

Этот подход работает хорошо, но мне интересно, есть ли некоторые крайние случаи, в которых он может не сработать?

Разумеется, я буду рад любым ответам с элегантными альтернативами, а также решениям для удаления пробелов с левой стороны строки.

5 ответ(ов)

1

Ваш подход вполне корректен и надежен. Я также долго использовал этот метод и пока не нашел более быстрого способа.

Ваш код выглядит следующим образом:

const char* ws = " \t\n\r\f\v";

// удаление пробелов с конца строки (право)
inline std::string& rtrim(std::string& s, const char* t = ws)
{
    s.erase(s.find_last_not_of(t) + 1);
    return s;
}

// удаление пробелов в начале строки (лево)
inline std::string& ltrim(std::string& s, const char* t = ws)
{
    s.erase(0, s.find_first_not_of(t));
    return s;
}

// удаление пробелов с обоих концов строки (сначала право, затем лево)
inline std::string& trim(std::string& s, const char* t = ws)
{
    return ltrim(rtrim(s, t), t);
}

Предоставляя символы для обрезки, вы получаете гибкость в удалении не только символов пробела, но и эффективность, позволяя обрезать только те символы, которые вы хотите удалить.

0

Мне нравится решение, предложенное tzaman, но единственная проблема в том, что оно не удаляет пробелы из строки, содержащей только пробелы.

Чтобы исправить этот недостаток, добавьте вызов str.clear() между двумя линиями, отвечающими за обрезку:

std::stringstream trimmer;
trimmer << str;
str.clear();
trimmer >> str;

Таким образом, если строка состоит только из пробелов, она будет успешно очищена.

0

В случае пустой строки ваш код предполагает, что добавление 1 к string::npos дает 0. Однако string::npos имеет тип string::size_type, который является беззнаковым. Таким образом, вы полагаетесь на поведение переполнения при сложении.

0

Попробуйте этот код, он работает для меня:

inline std::string trim(std::string& str)
{
    str.erase(str.find_last_not_of(' ') + 1);         // удаление пробелов в конце
    str.erase(0, str.find_first_not_of(' '));          // удаление пробелов в начале
    return str;
}

Этот метод удаляет пробелы в начале и конце строки.

0

Ваша функция trim, написанная на C++, предназначена для удаления пробелов из начала и конца строки. Давайте разберем, как она работает, и я помогу перевести этот код на русский язык.

Вот ваш оригинальный код:

std::string trim(const std::string &s)
{
    std::string::const_iterator it = s.begin();
    while (it != s.end() && isspace(*it))
        it++;

    std::string::const_reverse_iterator rit = s.rbegin();
    while (rit.base() != it && isspace(*rit))
        rit++;

    return std::string(it, rit.base());
}

Функция использует два итератора: один для начала строки (прямой итератор it), а другой для конца строки (обратный итератор rit). Сначала она перемещает прямой итератор до первого ненормированного символа, пропуская все пробелы в начале строки. Затем она использует обратный итератор, чтобы опуститься до первого ненормированного символа с конца строки, пропуская пробелы в конце. Наконец, она возвращает новую строку, которая начинается с it и заканчивается перед rit.base().

Вот перевод вашей функции trim на русский:

std::string обрезать(const std::string &s)
{
    std::string::const_iterator ит = s.begin();
    while (ит != s.end() && isspace(*ит))
        ит++;

    std::string::const_reverse_iterator рит = s.rbegin();
    while (рит.base() != ит && isspace(*рит))
        рит++;

    return std::string(ит, рит.base());
}

Также, если вам нужно короткое объяснение по поводу использования этой функции, вы можете добавить следующее:

Описание: Эта функция удаляет пробелы из начала и конца заданной строки. Вы можете использовать обрезать(s) для получения строки без начальных и конечных пробелов.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь