Какой лучший способ обрезать std :: string? - PullRequest
722 голосов
/ 19 октября 2008

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

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

Работает нормально, но мне интересно, есть ли какие-нибудь конечные случаи, когда он может потерпеть неудачу?

Конечно, ответы с изящными альтернативами, а также с левым решением приветствуются.

Ответы [ 40 ]

1 голос
/ 27 марта 2013

Еще один вариант - удаляет один или несколько символов с обоих концов.

string strip(const string& s, const string& chars=" ") {
    size_t begin = 0;
    size_t end = s.size()-1;
    for(; begin < s.size(); begin++)
        if(chars.find_first_of(s[begin]) == string::npos)
            break;
    for(; end > begin; end--)
        if(chars.find_first_of(s[end]) == string::npos)
            break;
    return s.substr(begin, end-begin+1);
}
1 голос
/ 03 октября 2013

Как насчет этого ...?

#include <iostream>
#include <string>
#include <regex>

std::string ltrim( std::string str ) {
    return std::regex_replace( str, std::regex("^\\s+"), std::string("") );
}

std::string rtrim( std::string str ) {
    return std::regex_replace( str, std::regex("\\s+$"), std::string("") );
}

std::string trim( std::string str ) {
    return ltrim( rtrim( str ) );
}

int main() {

    std::string str = "   \t  this is a test string  \n   ";
    std::cout << "-" << trim( str ) << "-\n";
    return 0;

}

Примечание: я все еще относительно новичок в C ++, поэтому, пожалуйста, прости меня, если я не в курсе.

0 голосов
/ 10 февраля 2016

C ++ 11:

int i{};
string s = " h e ll \t\n  o";
string trim = " \n\t";

while ((i = s.find_first_of(trim)) != -1)
    s.erase(i,1);

cout << s;

выход:

hello

отлично работает и с пустыми строками

0 голосов
/ 26 сентября 2018

Ниже приведено одноразовое (может быть двухпроходное) решение. Он дважды проходит через часть пробелов строки и часть без пробелов один раз.

void trim(std::string& s) {                                                                                                                                                                                                               
    if (s.empty())                                                                                                                                                                                                                        
        return;                                                                                                                                                                                                                           

    int l = 0, r = s.size()  - 1;                                                                                                                                                                                                         

    while (l < s.size() && std::isspace(s[l++])); // l points to first non-whitespace char.                                                                                                                                               
    while (r >= 0 && std::isspace(s[r--])); // r points to last non-whitespace char.                                                                                                                                                      

    if (l > r)                                                                                                                                                                                                                            
        s = "";                                                                                                                                                                                                                           
    else {                                                                                                                                                                                                                                
        l--;                                                                                                                                                                                                                              
        r++;                                                                                                                                                                                                                              
        int wi = 0;                                                                                                                                                                                                                       
        while (l <= r)                                                                                                                                                                                                                    
            s[wi++] = s[l++];                                                                                                                                                                                                             
        s.erase(wi);                                                                                                                                                                                                                      
    }                                                                                                                                                                                                                                     
    return;                                                                                                                                                                                                                               
}                                          
0 голосов
/ 11 октября 2015

Я использую это:

void trim(string &str){
    int i=0;

    //left trim
    while (isspace(str[i])!=0)
        i++;
    str = str.substr(i,str.length()-i);

    //right trim
    i=str.length()-1;
    while (isspace(str[i])!=0)
        i--;
    str = str.substr(0,i+1);
}
0 голосов
/ 04 июля 2018

Это так раздражает, что я

  • надо гуглить
  • выясни, что я должен использовать ракетостроение
  • что в строке нет простой функции обрезки / касания

Для me это самый быстрый способ решить эту проблему:

CString tmp(line.c_str());
tmp = tmp.Trim().MakeLower();
string buffer = tmp;

Хорошо, круто, что я могу использовать лямбда-операции, итераторы и все такое. Но мне нужно иметь дело только со строкой вместо символа ...

0 голосов
/ 11 июля 2018

Я знаю, что это очень старый вопрос, но я добавил несколько строк кода к вашему, и он удаляет пробелы с обоих концов.

void trim(std::string &line){

    auto val = line.find_last_not_of(" \n\r\t") + 1;

    if(val == line.size() || val == std::string::npos){
        val = line.find_first_not_of(" \n\r\t");
        line = line.substr(val);
    }
    else
        line.erase(val);
}
0 голосов
/ 06 декабря 2015

Кажется, я действительно опаздываю на вечеринку - не могу поверить, что об этом спросили 7 лет назад!

Вот мой взгляд на проблему. Я работаю над проектом, и я не хотел сейчас сталкиваться с проблемой использования Boost.

std::string trim(std::string str) {
    if(str.length() == 0) return str;

    int beg = 0, end = str.length() - 1;
    while (str[beg] == ' ') {
        beg++;
    }

    while (str[end] == ' ') {
        end--;
    }

    return str.substr(beg, end - beg + 1);
}

Это решение будет обрезаться слева и справа.

0 голосов
/ 02 апреля 2014

Это что, хорошо? (Потому что этот пост полностью нуждается в другом ответе:)

string trimBegin(string str)
{
    string whites = "\t\r\n ";
    int i = 0;
    while (whites.find(str[i++]) != whites::npos);
    str.erase(0, i);
    return str;
}

Аналогичный случай для trimEnd, просто измените поляризацию, индексы.

0 голосов
/ 28 ноября 2013
std::string trim( std::string && str )
{
    size_t end = str.find_last_not_of( " \n\r\t" );
    if ( end != std::string::npos )
        str.resize( end + 1 );

    size_t start = str.find_first_not_of( " \n\r\t" );
    if ( start != std::string::npos )
        str = str.substr( start );

    return std::move( str );
}
...