如何截取一个std::string?

1001
我目前在我的程序中使用以下代码来去除所有的std::string的右空格:
std::string s;
s.erase(s.find_last_not_of(" \n\r\t")+1);

它运行良好,但我想知道是否存在一些极端情况会导致它失败?
当然,欢迎提供优雅的替代方案和左修剪解决方案。
52个回答

0
修剪左右两侧:
trimmed_str = std::regex_replace(original_str, std::regex{R"(^\s+|\s+$)"}, "");

去除右边空白:
trimmed_str = std::regex_replace(original_str, std::regex{R"(\s+$)"}, "");

左侧修剪:
trimmed_str = std::regex_replace(original_str, std::regex{R"(^\s+)"}, "");

注意:这个通用的this answer适用于所有边界空白字符(不仅仅是" "),因此它将删除制表符、换行符等,就像一个修剪函数应该做的那样。

0
这样行吗?(因为这篇文章完全需要另一个答案 :))
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 也是类似的情况,只需要反转极性-er,索引即可。


我不确定使用临时字符串进行比较的开销是多少,但我认为我更喜欢使用while (isspace(str[i++]));以获得清晰度。最大的动机因素实际上是我不得不阅读一些文档才能理解代码,因为我最初认为这个代码的复杂度是O(n^2)(正如你所知道的那样,它并不是)。然后可以将代码简化为string trimBegin(string str) { size_t i = 0; while(isspace(str[i++]); return str.erase(0, i); } - vmrob

0
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 );
}

0

我知道这是一个非常老的问题,但我已经在你的代码中添加了几行代码,并且它可以修剪两端的空格。

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

为什么不使用lambda?

auto no_space = [](char ch) -> bool {
  return !std::isspace<char>(ch, std::locale::classic());
};
auto ltrim = [](std::string& s) -> std::string& {
  s.erase(s.begin(), std::find_if(s.begin(), s.end(), no_space));
  return s;
};
auto rtrim = [](std::string& s) -> std::string& {
  s.erase(std::find_if(s.rbegin(), s.rend(), no_space).base(), s.end());
  return s;
};
auto trim_copy = [](std::string s) -> std::string& { return ltrim(rtrim(s)); };
auto trim = [](std::string& s) -> std::string& { return ltrim(rtrim(s)); };

0

去除字符串两端的空格。

string trim(const std::string &str){
    string result = "";
    size_t endIndex = str.size();
    while (endIndex > 0 && isblank(str[endIndex-1]))
        endIndex -= 1;
    for (size_t i=0; i<endIndex ; i+=1){
        char ch = str[i];
        if (!isblank(ch) || result.size()>0)
            result += ch;
    }
   return result;
}

0

被接受的答案,甚至是Boost的版本对我都不起作用,所以我写了以下版本:

std::string trim(const std::string& input) {
    std::stringstream string_stream;
    for (const auto character : input) {
        if (!isspace(character)) {
            string_stream << character;
        }
    }

    return string_stream.str();
}

这将从字符串中的任何位置删除任何空格字符,并返回一个新副本。


-1

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

即使是空字符串也能正常工作


1
您的代码会删除所有非空格字符之间的空格。这不是“trim”的预期行为。 - CITBL

-1

我已经阅读了大部分的答案,但是没有发现有人使用istringstream。

std::string text = "Let me split this into words";

std::istringstream iss(text);
std::vector<std::string> results((std::istream_iterator<std::string>(iss)),
                                 std::istream_iterator<std::string>());

结果是单词向量,它可以处理包含内部空格的字符串,希望这有所帮助。


-2

看起来我真的来晚了 - 我简直不敢相信这个问题是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);
}

这个解决方案将从左侧和右侧修剪。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接