noskipws有什么问题?

时间:2018-08-17 19:55:45

标签: c++ visual-c++

我无法使用以下模板功能。

/// Remove leading and trailing space and tab characters from a string.
/// @param[out] result  the string to remove leading and trailing spaces from
template<class T>
void TrimString(std::basic_string<T>& str)
{
    basic_string<T> s, strRslt;

    basic_stringstream<T> strstrm(str);

    // we need to trim the leading whitespace using the skipws flag from istream.
    strstrm >> s;

    if(!s.empty())
    {
        do
        {
            strRslt += s;
        }while(strstrm >> noskipws >> s);
    }


    str = strRslt;

    return;

}

本单元测试通过:

[TestMethod]
void TestNarrowStringTrim()
{
    std::string testString = "    test";
    TrimString(testString);
    Assert::IsTrue(testString == "test");
}

所以我也希望通过以下单元测试:

[TestMethod]
void TestNarrowStringTrim()
{
    std::string testString = "    test string";
    TrimString(testString);
    Assert::IsTrue(testString == "test string");
}

但是,由于某种原因,该函数末尾的str值为“ test”

有人可以帮我解决这个问题吗?

因为(大概可以肯定)相关,所以我在Visual Studio 2012中使用Visual C ++。

有关noskipws的MSDN文章也与ccpreference.com文章有所不同。我已经链接了两篇文章以进行比较。

MSDN noskipws

cppreference.com noskipws

1 个答案:

答案 0 :(得分:3)

当流遇到空格时,将停止从流中读取字符串。由于您禁用了skipws,因此读取的第一个字符是空格。因此,将读取空字符串并设置故障位。参见https://en.cppreference.com/w/cpp/string/basic_string/operator_ltltgtgt

VS 2012实现可能是正确的(您的代码也因gcc而失败),只是文档很差。

根本不需要使用流,查找和substr更加简单:

template<class T>
void TrimString( std::basic_string<T>& str)
{
    size_t begin = str.find_first_not_of(" \t");
    if ( begin == std::string::npos )
    {
        str.clear();
    }
    else
    {
        size_t end = str.find_last_not_of(" \t");
        str = str.substr( begin, end - begin + 1 );
    }
}

或更简单的是boost::trim()https://www.boost.org/doc/libs/1_68_0/doc/html/string_algo/usage.html#id-1.3.3.5.5