返回首页

公用事业的STL STD:字符串
很多程序员已经熟悉各种例程的字符串对象,如长度,子串,发现,的charAt,toLowerCase,toUpperCase,修剪,equalsIgnoreCase,startsWith,endsWith,parseInt的toString,分割,等等。
现在,如果你是使用STL和String类的std::string的,怎么你做一些事情,上述例程吗?
当然,性病::字符串提供了一些方法来落实上述的套路。它们是:长度():获取字符串的长度。SUBSTR():得到一个字符串的子串。()/运算符[]:在字符串中的指定位置的字符。查找/ rfind():搜索字符串中的一个子向前/向后方向。find_first_of():找到的第一个字符是任何指定的字符。find_first_not_of():找到的第一个字符是不是指定的任何字符。find_last_of():找到的最后一个字符是任何指定的字符。find_last_not_of():找到的最后一个字符是不是指定的任何字符。
请参阅更多STD文档:字符串方法。
不落实的一些例程象std::字符串的方法,但我们可以发现在algorithm.h办法做到这一点。当然,性病现有的方法:字符串也用于实现他们。一个字符串转换为大写/小写

std::transform(str.begin(), str.end(), str.begin(), tolower);

std::transform(str.begin(), str.end(), str.begin(), toupper);

在std的详细信息,请参阅文档:转换函数。旁边一个字符串修剪空间修剪左边的空间{C}修剪正确的空间
string::iterator i;

for (i = str.end() - 1; ;i--) {

    if (!isspace(*i)) {

        str.erase(i + 1, str.end());

        break;

    }

    if (i == str.begin()) {

        str.clear();

        break;

    }

}
修剪的双面空间
修剪左边的空格,然后修剪右空格。因此,双面的空间被修剪。创建重复的字符或子字符串
如果你想创建一个字符串重复一个子,你必须使用一个循环来实现它。
string repeat(const string& str, int n) {

    string s;

    for (int i = 0; i < n; i++) {

        s += str;

    }

    return s;

}

,但是如果你需要只是重复字符,性病::字符串有一个构造。
string repeat(char c, int n) {

    return string(n, c);

}
比较忽略大小写
这很有趣。我们要复制我们试图比较两个字符串。然后转换它为小写。最后,只是比较两个小写的字符串。StartsWith和EndsWithStartsWith
str.find(substr) == 0;

如果结果是真实的,STR与SUBSTR开始。EndsWith
size_t i = str.rfind(substr);

return (i != string::npos) && (i == (str.length() - substr.length()));

如果结果为真,STR与SUBSTR结束。
有另一种方式来做到这一点。只要左子串或右子串进行比较。因为我不想来计算如果字符串的长度是够了,我使用find和rfind做到这一点。解析数/从一个字符串,BOOL
这些例程,atoi,"亚",和一些其他的C函数确定。但我想使用C的方式做它。所以我选择的std::istringstream。类sstream.h。
模板函数可以做的最不包括BOOL值。
template<class T> parseString(const std::string& str) {

    T value;

    std::istringstream iss(str);

    iss >> value;

    return value;

}

模板函数可以解析真实的虚假和其他数字0。但它不能解析"falsequot;为假和"; truequot为true。所以我写了一个特殊的函数。
template<bool>

bool parseString(const std::string& str) {

    bool value;

    std::istringstream iss(str);

    iss >> boolalpha >> value;

    return value;

}

正如你看到的,我通过一个std::boolalpha标志的输入流,然后输入流可以识别文字bool值。
这是可能使用类似的方法来解析十六进制字符串。这一次,我应该通过一个std::十六进制标志流。
template<class T> parseHexString(const std::string& str) {

    T value;

    std::istringstream iss(str);

    iss >> hex >> value;

    return value;

}
到字符串例程
从字符串解析一样,我会使用std::ostringstream从其他种类的值的字符串。类也在sstream.h。这里显示了相对的三个功能。
template<class T> std::string toString(const T& value) {

    std::ostringstream oss;

    oss << value;

    return oss.str();

}

string toString(const bool& value) {

    ostringstream oss;

    oss << boolalpha << value;

    return oss.str();

}

template<class T> std::string toHexString(const T& value, int width) {

    std::ostringstream oss;

    oss << hex;

    if (width > 0) {

        oss << setw(width) 

            << setfill('0');

    }

    oss << value;

    return oss.str();

}

你注意环境运输及工务局局长和setfill?他们仍然需要一个参数的标志。性病::环境运输及工务局局长可以使输出的事流中占据一个固定的宽度。如果它的长度是不够的,默认情况下它使用空格来填补。性病::setfill是用来改变的空间持有人。如果你想控制的对齐,还有的std::左和std::正确的标志。
哦,我忘了告诉你,环境运输及工务局局长和setfill需要iomanip.h头文件。分流和标记生成器
我觉得split函数应实施一个标记生成器。所以我写了一个分词器第一。我们可以使用的find_first_of和find_first_not_of方法,以获取每个令牌。下面显示的是标记生成器类的nextToken方法。
bool Tokenizer::nextToken(const std::string& delimiters) {

    // find the start character of the next token.

    size_t i = m_String.find_first_not_of(delimiters, m_Offset);

    if (i == string::npos) {

        m_Offset = m_String.length();

        return false;

    }



    // find the end of the token.

    size_t j = m_String.find_first_of(delimiters, i);

    if (j == string::npos) {

        m_Token = m_String.substr(i);

        m_Offset = m_String.length();

        return true;

    }



    // to intercept the token and save current position

    m_Token = m_String.substr(i, j - i);

    m_Offset = j;

    return true;

}

完整的分解器的源代码归档。您可以从上面的链接下载。所有其他的功能仍然在源代码文件。

回答

评论会员:dourgulf 时间:2011/12/14
find_first_of将设法找到SUBSTR SUBSTR str中,事件,如果不领先的STR分字符串
!如:STR ="1234567890",SUBSTR ="0";
评论会员:狮身人面像 时间:2011/12/14
哎呀!有没有basic_string.clear()方法执行在VC6 ...
评论会员:Huyong赵 时间:2011/12/14
你的文章是非常有用的{S0}
我刚刚访问了您的博客,发现你从绵阳。我希望您和您的家人和你的朋友都OK
评论会员:。会员4412190 时间:2011/12/14
我的家人没有人受伤。谢谢。

-----------------------{ BR}詹姆斯花式(GTM 8.00)
评论会员:ana_v123 时间:2011/12/14
endswith返回true如果SUBSTR比STR不再是一个字符。它需要一个额外的长度检查。
评论会员:巴勃罗Aliskevicius 时间:2011/12/14
谢谢
我已经修改了它。

-----------------------{ BR}詹姆斯花式(GTM 8.00)
评论会员:liangtao 时间:2011/12/14
std::字符串(VC 6,STL版本)会导致内存多处理器电脑上的腐败

MSDN网站的文章给给定的几个变通办法。任何一个有经验丰富的哪一个更适合的VC 6,各种运行的Windows(98/ME/2000/XP/2003)(不升级。NET)应用程序的选择吗?

分享您的意见表示感谢。
安娜

Ana_v123
评论会员:珠 时间:2011/12/14
"的MSDN网站的文章"

能否请您添加的网址是什么?
非常感谢,
巴勃罗。
"意外:一个必然发生的,由于不可改变的自然法则的行动。" (刘汉铨比尔斯,大约1899年)
评论会员:珠 时间:2011/12/14
嗨,

我建立这个测试案例,但它生成错误。我的g是4.1.1。我不知道为什么
如果有一个错误的使用,请告诉我如何使用它

谢谢


#包括lt; iostreamgt;
#包括LT; sstreamgt;
使用命名空间std;


templatelt类TGT,T parseString(常量性病::stringamp; STR)
NBSP T值;
STD:istringstream ISS(STR);
ISS GT GT;值;
返回值;
}

INT主要(){
法院LT ; LT"你好世界!!!" < !! 诠释一个= parseString("123");
coutlt LT; ALT 返回0;
}
评论会员:pjr1 时间:2011/12/14
您应该指定模板参数时调用模板函数。

INT A = parseString("123")

如果你调用parseString("123"),该函数可以转换为std"123"::字符串,但它不能决定返回哪种类型的值。所以,你必须明确指定。

-----------------------{ BR}詹姆斯花式(GTM 8.00)
评论会员:游客 时间:2011/12/14
CN_AHON​​G
您好J.范:

谢谢您的短期和不错的文章。

当代码被编译,转换或std::变换了编译错误作为波纹管:

当它是"STD:改造",错误消息
错误C2039:"转变":不是"性病"
错误C2065:"转变":未声明的标识符

而如果是"改造"

错误C2065:"转变":未声明的标识符

该代码是
性病::字符串tolower的(常量的std::字符串str)
{
&# 160; 性病::字符串T = STR
 60;
的std::变换(t.begin(),t.end()中,t.begin(),tolower的); 返回T;
}

我到STL,我可能会错过的东​​西。我用VC6.0的SP6和当前的SDK

能否请你告诉我,我是否做错了?
感谢您的帮助,你。 欢呼声,

评论会员:dlc0613 时间:2011/12/14
您需要的#include <算法>

如果你下载我的源代码,你可以在strutil.cpp找到include语句。

STD:变换(...)是一个STL函数算法宣布。

-----------------------{ BR}詹姆斯花式(GTM 8.00)
评论会员:Gernot弗里希 时间:2011/12/14
。詹姆斯花式很多的感谢

它的工作原理。

欢呼声,