C++
- 前言
- getline
- length, size
- c_str
- append, insert
- erase
- find
- substr
- isspace, isdigit
前言
C++是兼容C语言的,所以C++的字符串自然继承C语言的一切字符串,但它也衍生出属于自己的字符串类,即String类。String更像是一个容器,但它与容器还是有一些差别,我看网上很多人直接把它等同于一种容器,这种说法大概是有错误的。。。
string类的相关方法很多,下面我只记录一下我个人常用到的一些方法,必然不详实,仅供参考。
所有用到string类的地方都至少需要一个string的头文件,如果还需要其它的,我们另外注明。
#include <string>
getline
从用户端接收字符串方法其实挺多的,C语言中最常见的就是scanf函数了,类比这个函数,C++也可以用cin>>…的方式接收用户输入。但这两者都只能接收一个单词,或一个数字,因为它们会以空格符作为结尾。可以看看以下这个例子。
string s;
cout <<"please enter a string: ";
cin >> s;
cout << s <<endl;
输出结果如下:
以空格为结尾的接收输入函数显然不是我们所希望的,一句话,难免有许多空格。那么这时候就需要用到getline函数了,这个函数读取的字符串会以换行符”\n“为结尾。
string s1;
cout <<"please enter a string: ";
getline(cin, s1);
cout << s1 <<endl;
getline有两个参数,第一个传入参数是获取字符串的地方,第二个传入参数是字符串存放的地方。这里获取用户端输入,所以第一个参数就是cin了。
程序运行结果如下:
length, size
length是C++早期读取字符串长度的唯一方法,但后面为了兼容容器类,又推出了size方法。两者的作用是一模一样的。调用该函数会返回字符串的字符数,而非字节数。
用法也十分简单:
string s1;
cout <<"please enter a string: ";
getline(cin, s1);
cout << s1.length() <<endl;
程序运行结果如下,注意空格也算一个字符。
c_str
c_str方法的作用是把C++的字符串类转化为常规的字符串,即变成可以用指针索引的字符串。因为有些函数要求传入参数是" char * "。比如open函数。
看下面这个例程,c_str只能转化为const char* 类型。并且由于字符指针指向的只能是一个字符,所以打印的时候需要用for循环打印出来。
string path = "/home/object_file";
const char *f;
f = path.c_str();
for(int i=0; i<path.length(); i++)
{
cout<< f[i];
}
cout<<"\n";
不过如果用C语言的printf函数,倒可以免去使用for循环,直接用%s告诉计算机这是一个字符串即可。
string path = "/home/object_file";
const char *f;
f = path.c_str();
printf("%s \n", f);
有string类转化为const char*,那放过来char *转化为string类也可以。操作十分简单,只需要直接赋值就行。
char temp[15] = "hello world";
string s = temp;
cout << s << endl;
append, insert
append方法和insert方法都是在原来的字符串的基础上添加某些东西,但前者是添加在字符串后面,后者则可以添加到指定位置。它们的用法都比较简单,直接看以下例子。
string s1 = "hello ";
string s2 = "word";
s1.append("wrold");
s2.insert(0, "add a "); //第一个参数是插入的位置,第二个参数是插入的字符串
cout <<"s1: "<< s1 << endl;
cout <<"s2: "<< s2 << endl;
以上程序的运行情况如下:
s1: hello world
s2: add a word
erase
erase方法用来擦除字符串中的某些字符,在处理数据的时候还挺有用的。
直接看一个例子:
string s = "hello world!";
s.erase(3, 2);
cout << s << endl;
程序运行结果如下:
可见,erase第一个传入参数是起始位置,第二个传入参数擦除的字符个数。如果没有添加第二个参数则视为,在擦除起始位置之后的全部字符。可以看个例子:
string s = "hello world!";
s.erase(3);
cout << s << endl; //打印结果是hel
熟悉C++容器的朋友大概会发现,这与容器的erase方法有一些不一样。以vector为例,erase(begin, end)的第一个参数是要擦除的起始位置,第二个位置是要擦除的结束位置,如果第二个参数不写,就默认只擦除一个成员。
find
find方法是从字符串中查找某个特定的字符,并且返回该字符第一次出现时的位置。当然find方法也有很多衍生方法,比如find_first_of, find_last_of等等。而对于这些衍生方法,大家有兴趣可以自行查阅相关资料。我这里就只说一下find的一些常规应用。
string s = "hello world!";
int loc = s.find("o");
cout << loc << endl;
在"hello world!"这个字符串中,"o"第一个出现的位置是4,所以打印结果就是4。
而如果我们像知道"o"第二次出现的地方呢?可以参考以下这个例程:
string s = "hello world!";
int loc = s.find("o");
int cnt = 1;
while(loc != string::npos)
{
if(cnt == 2)
break;
loc = s.find("o", loc+1);
cnt ++;
}
cout << loc <<endl;
程序输出结果如下:
在"hello world!"这个字符中,"o"第二次出现的位置确实是7,符合预期。
那么总结一下,find有两个传入参数,第一个传入参数是期望查找的字符,第一个传入参数是字符串中搜索区域的起始位置,如果没有这个参数,则默认从头开始搜索。
find方法的返回值就是被搜索字符首次出现的位置,如果没有找到该字符,则返回string::npos。
substr
substr方法用于截取字符串中的某一段,它有两个参数,第一个参数是截取区间的起点,第二个参数是截取区间的终点。返回值是所截取出来的字符串。
以下例程的作用是将"hello world!"中的hello截取出来:
string s = "hello world!";
string sp = s.substr(0, 5);
cout << sp << endl;
isspace, isdigit
isspace和isdigit分别是判断字符串中的空格和数字的函数,调用这两个函数的时候需要添加头文件cctype。其实这两个函数不是C++string类特有的,C语言中的字符串也可以用。
#include <cctype>
看个例子吧,该例子欲将"hello world!"中的空格抹去。
string s = "hello world!";
for(int i=0; i<s.length(); i++)
{
if(isspace(s[i])){
s.erase(i, 1);
i--;
}
}
cout << s <<endl;
isspace的返回值是一个int类型,如果检查到空格就返回一个非零数据,否则返回0.
突然想到另一种消除空格方法,也一并写出来吧。
string s = "hello world!";
int cnt = 0;
for(char i : s)
{
if(i == ' ')
{
s.erase(cnt, 1);
cnt--;
}
cnt ++;
}
cout << s <<endl;
接下来再来看看isdigit的用法,isdigit和isspace的返回值很像,都是检查到目标则返回非零数字,否则返回0.
在本例程中,我欲将字符串"hello 123 world!"的数字打印出来。
string s = "hello 123 world!";
for(int i=0; i<s.length(); i++)
{
if(isdigit(s[i]))
{
int temp = s[i] - '0';
cout<< temp;
}
}
cout <<"\n";
输出结果如下: