Форум программистов, компьютерный форум CyberForum.ru

std::string Трим - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 35, средняя оценка - 4.63
insideone
Модератор
Автор FAQ
 Аватар для insideone
3620 / 898 / 47
Регистрация: 10.01.2010
Сообщений: 2,422
15.02.2010, 18:00     std::string Трим #1
Как сделать трим (вырезание из начала\конца строки лишних символов таких как пробелы, табуляции...) в std::string? Я недавно нашёл у себя в коде такое:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    void LTrim(std::string* String, const char* Trim)
    {
        int i = 0;
        while ( Trim[i] )
        {
            // Если текущий символ - трим-символ
            if ( (*String)[0] == Trim[i] )
            {
                //удаляем его и начинаем проверку заново
                String->erase(0, 1);
                i = 0;
                continue;
            }
            // Следующий символ считающийся Trim
            i++;
        }
    }
Мне кажется это страшная вещь Как сделать правильно?
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.02.2010, 18:00     std::string Трим
Посмотрите здесь:

C++ запрошено преобразование от ‘const std::string*’ к нескалярному типу ‘std::string’
C++ Здравствуйте! Создал класс std::string. Не создается объкт типа string... Подскажите в чем причина?
C++ Где и почему используют ту или иную строку std::string, char[], System::String^ ?
Ошибка: отсутствует оператор ">>"; типы операндов: std::istream >> std::string C++
C++ ошибка в программе (cannot convert 'std::string {aka std::basic_string<char>}' to 'const char*')
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
mirso
523 / 341 / 17
Регистрация: 05.04.2009
Сообщений: 709
21.02.2010, 21:42     std::string Трим #2
insideone,
Цитата Сообщение от insideone Посмотреть сообщение
вырезание из начала\конца строки лишних символов таких как пробелы, табуляции
Вариант
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <ctype.h>
 
int main()//=========================================================
{
    std::string s = "   a b  c     ";
 
    std::cout << '>' << s << "<\n";
    //---------------------------------------------------------
    while ( isspace( *s.begin() ) ) s.erase(0, 1);
    while ( isspace( *--s.end() ) ) s.erase(s.length() - 1, 1);
    //---------------------------------------------------------
    std::cout << '>' << s << '<';    
   
    return 0;
}//==================================================================
insideone
Модератор
Автор FAQ
 Аватар для insideone
3620 / 898 / 47
Регистрация: 10.01.2010
Сообщений: 2,422
21.02.2010, 21:53  [ТС]     std::string Трим #3
2 mirso довольно кратно и понятно, однако мне как раз и не хочется вызвать .erase много раз. Пожалуй лучшим способом будет нахождение последнего (x) пробела с начала строки и .erase(0, x). Тоже самое с тримом справа. Просто у меня операция трима достаточно частоприменяемая и влияет на загрузку приложения в целом, поэтому хотелось сделать как можно лучше)
outoftime
║XLR8║
 Аватар для outoftime
505 / 427 / 33
Регистрация: 25.07.2009
Сообщений: 2,297
21.02.2010, 21:56     std::string Трим #4
Сообщение было отмечено автором темы, экспертом или модератором как ответ
C++
1
2
3
4
5
6
7
void Delete(std::string &s)
{
      int i = 0, j = s.size()-1;
      while (s[i] == ' ' || s[i] == '\t') ++i;
      while (s[j] == ' ' || s[j] == '\t') --j;
      s = s.substr(i, s.size() - (i + (s.size()-j+1)) );
}
Добавлено через 1 минуту
insideone, писал на форуме, продебаж и исправь ошибки..
@KOT@
81 / 39 / 2
Регистрация: 29.01.2010
Сообщений: 386
21.02.2010, 22:00     std::string Трим #5
Цитата Сообщение от insideone Посмотреть сообщение
i = 0;
Помоему не надо делать и нулевым - зачем перебирать массив с самого начала? (или может я что-то не понял)
i-=1


Цитата Сообщение от insideone Посмотреть сообщение
Пожалуй лучшим способом будет нахождение последнего (x) пробела с начала строки и .erase(0, x). Тоже самое с тримом справа.
не совсем понял. Чем это отличается от предыдущего?
insideone
Модератор
Автор FAQ
 Аватар для insideone
3620 / 898 / 47
Регистрация: 10.01.2010
Сообщений: 2,422
21.02.2010, 22:16  [ТС]     std::string Трим #6
2 outoftime Выглядит отлично, спасибо

Помоему не надо делать и нулевым - зачем перебирать массив с самого начала? (или может я что-то не понял)
i-=1
Ну а как же ещё. Может первый символ и есть пробел
не совсем понял. Чем это отличается от предыдущего?
Функция вызываемая в цикле и функция вызываемая 1 раз это разные вещи))
outoftime
║XLR8║
 Аватар для outoftime
505 / 427 / 33
Регистрация: 25.07.2009
Сообщений: 2,297
21.02.2010, 22:25     std::string Трим #7
insideone, я вот не знаю что будет быстрее брать трижды s.size() или сохрать размер в переменную int sz= s.size(); и далее производить вычисления..
И если уже совсем на оптимизацию сойти, то быстрее юзать сишные строки..
insideone
Модератор
Автор FAQ
 Аватар для insideone
3620 / 898 / 47
Регистрация: 10.01.2010
Сообщений: 2,422
21.02.2010, 22:43  [ТС]     std::string Трим #8
Цитата Сообщение от outoftime Посмотреть сообщение
я вот не знаю что будет быстрее брать трижды s.size() или сохрать размер в переменную int sz= s.size(); и далее производить вычисления..
Наверное сохранять размер в переменной лучше, я читал что в стеке память выделяется шустро.

И если уже совсем на оптимизацию сойти, то быстрее юзать сишные строки..
Да я то с удовольствием просто эта строка считывается из файла через getline. Приходится в std::string. Нет. я конечно понимаю что считываь можно и по другому, просто так как то удобнее...
mirso
523 / 341 / 17
Регистрация: 05.04.2009
Сообщений: 709
21.02.2010, 22:49     std::string Трим #9
outoftime,
Цитата Сообщение от outoftime Посмотреть сообщение
s = s.substr(i, s.size() - (i + (s.size()-j+1)) );
обрезает последний символ
-------------------------------
так работает нормально
C++
1
s = s.substr(i, j - i + 1  );
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9371 / 5421 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
21.02.2010, 23:15     std::string Трим #10
вроде работает...
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
#include <string>
 
std::string& trimStr(std::string& s){
    static const std::string SPACES(" \t\n");
    size_t head = s.find_first_not_of(SPACES);
    if ( head == std::string::npos )
        return s = "";
    else if ( head > 0 )
        s.erase(0, head);
    size_t tail = s.find_last_not_of(SPACES);
    if ( tail != s.size() - 1 )
        s.erase(tail + 1);
    return s;
}
 
int main(){
    std::string str;
    while ( true ){
        std::cout << "String: ";
        std::getline(std::cin, str);
        if ( str.empty() )
            break;
        std::cout << "Befor: \"" << str << "\"" << std::endl;
        trimStr(str);
        std::cout << "After: \"" << str << "\"" << std::endl;
    }
    
    return 0;
}
insideone
Модератор
Автор FAQ
 Аватар для insideone
3620 / 898 / 47
Регистрация: 10.01.2010
Сообщений: 2,422
21.02.2010, 23:26  [ТС]     std::string Трим #11
Цитата Сообщение от easybudda Посмотреть сообщение
вроде работает...
работает. этот вариант хорош тем что расширяем - можно выбирать что считать за лишний символ, удобно
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9371 / 5421 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
21.02.2010, 23:41     std::string Трим #12
Цитата Сообщение от insideone Посмотреть сообщение
этот вариант хорош тем что расширяем - можно выбирать что считать за лишний символ
Ага... Немного переделав, можно, как дополнительный параметр, передавать строку символов для удаления...
insideone
Модератор
Автор FAQ
 Аватар для insideone
3620 / 898 / 47
Регистрация: 10.01.2010
Сообщений: 2,422
21.02.2010, 23:46  [ТС]     std::string Трим #13
C++
1
2
3
4
5
6
7
8
9
10
11
12
std::string& trimStr(std::string& s, std::string SPACES){
        //static const std::string SPACES(" \t\n");
        size_t head = s.find_first_not_of(SPACES);
        if ( head == std::string::npos )
                return s = "";
        else if ( head > 0 )
                s.erase(0, head);
        size_t tail = s.find_last_not_of(SPACES);
        if ( tail != s.size() - 1 )
                s.erase(tail + 1);
        return s;
}
Пожалуй так?
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9371 / 5421 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
22.02.2010, 00:09     std::string Трим #14
Цитата Сообщение от insideone Посмотреть сообщение
std::string& trimStr(std::string& s, std::string SPACES)
лучше
C++
1
std::string& trimStr(std::string& s, const std::string& SPACES = " \t\n")
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.03.2011, 01:48     std::string Трим
Еще ссылки по теме:

C++ Как правильно перевести std::wstring в std::string ?
C++ Как привести std::wstring к std::string?
C++ Std::string and std::wstring convert

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
half-node
21 / 18 / 3
Регистрация: 12.08.2010
Сообщений: 206
13.03.2011, 01:48     std::string Трим #15
Подниму тему.
Объясните пожалуйста, почему в CString методы Trim/TrimLeft/TrimRight - реализованы, а в обычном string - нет?
На это есть реальные причины?
Yandex
Объявления
13.03.2011, 01:48     std::string Трим
Ответ Создать тему

Метки
std::string, stl, Строки
Опции темы

Текущее время: 00:13. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru