C++ 从字符串中修剪空格

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25829143/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 11:26:37  来源:igfitidea点击:

Trim whitespace from a String

c++stringwhitespacetrim

提问by follmer

I know there are several ways to do this in Java and C that are nice, but in C++ I can't seem to find a way to easily implement a string trimming function.

我知道在 Java 和 C 中有几种很好的方法可以做到这一点,但是在 C++ 中,我似乎无法找到一种轻松实现字符串修剪功能的方法。

This is what I currently have:

这是我目前拥有的:

string trim(string& str)
{
    size_t first = str.find_first_not_of(' ');
    size_t last = str.find_last_not_of(' ');
    return str.substr(first, (last-first+1));
}

but whenever I try and call

但每当我尝试打电话时

trim(myString);

I get the compiler error

我收到编译器错误

/tmp/ccZZKSEq.o: In function `song::Read(std::basic_ifstream<char, 
std::char_traits<char> >&, std::basic_ifstream<char, std::char_traits<char> >&, char const*, char const*)':
song.cpp:(.text+0x31c): undefined reference to `song::trim(std::string&)'
collect2: error: ld returned 1 exit status

I am trying to find a simple and standard way of trimming leading and trailing whitespace from a string without it taking up 100 lines of code, and I tried using regex, but could not get that to work as well.

我试图找到一种简单而标准的方法来修剪字符串中的前导和尾随空格而不占用 100 行代码,并且我尝试使用正则表达式,但无法使其正常工作。

I also cannot use Boost.

我也无法使用 Boost。

回答by Anthony Kong

Your code is fine. What you are seeing is a linker issue.

你的代码没问题。您看到的是链接器问题。

If you put your code in a single file like this:

如果您将代码放在这样的单个文件中:

#include <iostream>
#include <string>

using namespace std;

string trim(const string& str)
{
    size_t first = str.find_first_not_of(' ');
    if (string::npos == first)
    {
        return str;
    }
    size_t last = str.find_last_not_of(' ');
    return str.substr(first, (last - first + 1));
}

int main() {
    string s = "abc ";
    cout << trim(s);

}

then do g++ test.ccand run a.out, you will see it works.

然后执行g++ test.cc并运行 a.out,您将看到它的工作原理。

You should check if the file that contains the trimfunction is included in the link stage of your compilation process.

您应该检查包含该trim函数的文件是否包含在编译过程的链接阶段。

回答by jha-G

Here is how you can do it:

您可以这样做:

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

And the supportive functions are implemeted as:

支持功能实现为:

std::string & ltrim(std::string & str)
{
  auto it2 =  std::find_if( str.begin() , str.end() , [](char ch){ return !std::isspace<char>(ch , std::locale::classic() ) ; } );
  str.erase( str.begin() , it2);
  return str;   
}

std::string & rtrim(std::string & str)
{
  auto it1 =  std::find_if( str.rbegin() , str.rend() , [](char ch){ return !std::isspace<char>(ch , std::locale::classic() ) ; } );
  str.erase( it1.base() , str.end() );
  return str;   
}

And once you've all these in place, you can write this as well:

一旦你准备好所有这些,你也可以这样写:

std::string trim_copy(std::string const & str)
{
   auto s = str;
   return ltrim(rtrim(s));
}

Try this

尝试这个

回答by Martin

I think that substr() throws an exception if str only contains the whitespace.

我认为如果 str 仅包含空格,则 substr() 会引发异常。

I would modify it to the following code:

我将其修改为以下代码:

string trim(string& str)
{
    size_t first = str.find_first_not_of(' ');
    if (first == std::string::npos)
        return "";
    size_t last = str.find_last_not_of(' ');
    return str.substr(first, (last-first+1));
}

回答by Will

#include <vector>
#include <numeric>
#include <sstream>
#include <iterator>

void Trim(std::string& inputString)
{
    std::istringstream stringStream(inputString);
    std::vector<std::string> tokens((std::istream_iterator<std::string>(stringStream)), std::istream_iterator<std::string>());

    inputString = std::accumulate(std::next(tokens.begin()), tokens.end(),
                                 tokens[0], // start with first element
                                 [](std::string a, std::string b) { return a + " " + b; });
}

回答by ivan.ukr

In addition to answer of @gjha:

除了@gjha的回答:

inline std::string ltrim_copy(const std::string& str)
{
    auto it = std::find_if(str.cbegin(), str.cend(),
        [](char ch) { return !std::isspace<char>(ch, std::locale::classic()); });
    return std::string(it, str.cend());
}

inline std::string rtrim_copy(const std::string& str)
{
    auto it = std::find_if(str.crbegin(), str.crend(),
        [](char ch) { return !std::isspace<char>(ch, std::locale::classic()); });
    return it == str.crend() ? std::string() : std::string(str.cbegin(), ++it.base());
}

inline std::string trim_copy(const std::string& str)
{
    auto it1 = std::find_if(str.cbegin(), str.cend(),
        [](char ch) { return !std::isspace<char>(ch, std::locale::classic()); });
    if (it1 == str.cend()) {
        return std::string();
    }
    auto it2 = std::find_if(str.crbegin(), str.crend(),
        [](char ch) { return !std::isspace<char>(ch, std::locale::classic()); });
    return it2 == str.crend() ? std::string(it1, str.cend()) : std::string(it1, ++it2.base());
}