C里面提供了很多的函数可以方便的进行字符的判断与转换字符串,但如果是在写C++程序时,应该尽量使用标准C++的处理方法,这里将简要介绍几种常用的处理方法。
1.string类的原型
string其实是一个用typedef定义的类型,定义在<string>头文件中,原型为:
std {
template< class charT, class traits= char_traits<charT>,class Allocator= allocator<charT> >
class basic_string;
typedef basic_string<char> string;
typedef basic_string<wchar_t> wstring
}
上面string等同于basic_string的char类型,也是一个模板类,只是模板参数固化为char类型了。string用于普通ASCII字符串操作,而wstring是basic_string的wide char类型实作版,用于Unicode字符串操作。
2.将C字符串转换为C++的string类型
//方法1:初始化类方法
char *cstr= “hello world”;
std::string str(cstr);
//或者:方法2:/赋值方法
char *cstr= “hello world”;
std::string str;
str.assign(cstr);
//或者:方法3:与assign函数等效
char *cstr= “hello world”;
std::string str;
str=cstr;
说明:string类的=操作符重载函数,将指针字符串转换为string类,在它的内部实现中其实也是调用assign()函数。
3.将C++的string类型转换为C字符串
std::string str(“hello world”);
char* cstr;
cstr= str.c_str();
说明:string类的c_str()函数返回C指针样式的字符串,注意返回的字符串会在未尾追加”\0”,与之对应的data()函数也返回C指针的字符串,但不追加”\0”,在使用cstr时应该小心,因为它只是string类中字符串缓冲区的指针,当改变string的值后,该指针将无效。
4.将string类型转换为int,long等数值类型
string是不能直接转换为数值类型,这里需要一个字符串流来中转,可以用于转换的字符串类有istringstream, ostringstream, stringstream,在<sstream>头文件中声明,关于它们详细的使用方法请参考相关与教程,下面是它们的原型申明:
namespace std{
template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> > class basic_istringstream;
typedef basic_istringstream<char> istringstream;
typedef basic_istringstream<wchar_t> wistringstream;
template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> > class basic_ostringstream;
typedef basic_ostringstream<char> ostringstream;
typedef basic_ostringstream<wchar_t> wostringstream;
template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> > class basic_stringstream;
typedef basic_stringstream<char> stringstream;
typedef basic_stringstream<wchar_t> wstringstream;
}
其中istringstream用于字符串缓冲区输入操作,ostringstream用于字符串缓冲区输出操作,stringstream既可用于输入,也可用于输出。
int i;
float f;
std::string stri(“10”);
std::string strf(“10.3”);
std::istringstream istri(stri);//使用stri来初始化istringstream
std::istringstream istrf(strf);//使用strf来初始化istringstream
istri>>i;
istrf>>f;
结果:
i = 10;
f = 10.3;
5.将数值类型转换为string 类字符串
int i=10;
std::string str;
std::ostringstream ostr;
ostr<<i;//将i输出到ostringstream缓冲区中
str= ostr.str();//取出 ostringstream中的字符串
其中ostringstream的str()函数返回缓冲区的string字符串,带参数时则重新设置缓冲区的字符串。
6.string的遍历
这里我们没有必要再用C的方法来对字符串遍历,C++提供了很好用的遍历方法,以下是C样式的遍历:
C++中很多容器类中提供了iterator嵌套类,用来遍历该容器中的元素,string也不例外,下面是使用string的iterator遍历示例:
std::string str(“hello world”);
std::string::iterator pos;
for( pos=str.begin(); pos!=str.end(); pos++)
{
char c=*pos; // 取其中一个字符
// todo
}
7.一个综合转换的例子
它从命令行得到一个十六进制样式的字符串,将它转换为十进制模式的字符串存储到string中,然后遍历string,以十六进制的行式输出到终端。
//stringtest.cpp
#include<iostream>
#include<sstream>
#include<iomanip>
int main(int argc, char** argv)
{
if( argc<=1)
return 0;
std::stringstream buf;
std::string str;
for(int i=1; i<argc; i++)
{
int num;
buf.clear();//清除buf的所有错误标志
buf.str(argv[i]);
buf>>std::hex>>num;//注意此时buf会置eof标志
str+= (char)num;
}
std::cout<<"str(dec)="<<str<<std::endl;
std::string::iterator pos;
std::cout<<"std(hex)=";
for( pos=str.begin(); pos!=str.end(); pos++)
{
//以两个十六进制数行式输出,用空格分隔
std::cout<<std::setfill('0')<<std::setw(2);
//注意string保存的是有符号字符串,而真实的值是无符号的,需要转换成
//正确的值,而std::hex标志只对int等数值起作用,所以还要转换成int
std::cout<<std::hex<<(int)(unsigned char)*pos<<" ";
}
std::cout<<std::endl;
return 0;
}
编译此程序:
g++ stringtest.cpp -o stringtest
下面是测试数据:
[root]# ./stringtest 01 02 03 45 a3 e8 str(dec)=###E� std(hex)=01 02 03 45 a3 e8 [root]# ./stringtest 68 65 6c 6c 6f str(dec)=hello std(hex)=68 65 6c 6c 6f
8.小结
本文简要介绍了string转换的一些方法,string的简单遍历,以及string stream转换的方法,让我们在写程序时把精力放在程序逻辑上,而不用关心C字符串的细节,及大小分配问题。
9.相关参考
<<C++标准程序库>> (侯捷/孟岩 译) 华中科技大学社