本文特记录C++中string类(注意string是一个类)的一些值得注意的地方。

string类的实例是以‘\0'结束的吗?

   这个问题有时还真容易混淆,因为我们可能会将 C++ 语言中的string类的实例跟 C 语言的字符串相混淆。在 C 语言中,字符串是以’\0'结束的字符数组。但C++还提供了string类,跟 C 语言字符串是完全不一样的东西,但却容易相互混淆。

  我们先来看一下,对于string类而言,'\0'跟其他字符是否有不一样的意义。

  实际上,‘\0’在string类之中并不具有特殊意义,它跟其他字符的地位完全相同。为了证明这个说法,我们来看一个例子:

 1 #include <iostream>
 2 #include <string>
 3 using namespace std;
 4 
 5 int main()
 6 {
 7     string in{"abc"};
 8     in.push_back('\0');
 9     in.append("def");
10     cout << in << endl;
11 
12     return 0;
13 }

  我们将断点设定在第10行,可以发现有如此结果:

  (C++)string类杂记_操作符

  另外,程序输出如下:

  (C++)string类杂记_ios_02

  从上述结果可以看出,'\0'在string类中确跟其他字符的地位一样。

  同时,我们也可以知道string类的实例并不以'\0'结束。不过,我们再看看下边例子,我们可能会动摇这个结论:

 1 #include <iostream>
 2 #include <string>
 3 using namespace std;
 4 
 5 int main()
 6 {
 7     string in{"abcdef"};
 8     int i = 0;
 9     while (in[i] != '\0')
10     {
11         cout << in[i] << " ";
12         i++;
13     }
14     cout << endl;
15 
16     return 0;
17 }

  程序运行结果如下:

  (C++)string类杂记_ios_03

  从这个程序来看,string类的实例好像又是以'\0'结束的。实际上,是操作符'[]'捣的鬼。对于string类而言,操作符’[]‘并不检查索引是否有效,所以当索引越界时,操作符'[]'的访问行为是不明确的。不过对于string类而言,用操作符'[]'访问第length()个字符时会返回'\0',而对第length()+1以上的访问会使得程序崩溃。这个可以通过上边程序的 in 变量的原始视图来验证到:

  (C++)string类杂记_字符串_04

  但是这并不能证明string类的实例就以'\0'结束。如果我们用string类提供的会进行类型检查的成员函数 at 来访问实例中的字符,就会发现上一程序会发生越界错误:

 1 #include <iostream>
 2 #include <string>
 3 using namespace std;
 4 
 5 int main()
 6 {
 7     string in{"abcdef"};
 8     int i = 0;
 9     while (in.at(i) != '\0')
10     {
11         cout << in[i] << " ";
12         i++;
13     }
14     cout << endl;
15 
16     return 0;
17 }

  程序运行时错误:

  (C++)string类杂记_字符串_05

  

  综上所述,‘\0’在string类之中并不具有特殊意义,它跟其他字符的地位完全相同,而且string类的实例也并不以'\0'结束。

string类实例与 C 语言字符串转换

   将string类实例转换为 C 语言字符串是比较常见的,一般利用的是c_str()函数,如下例:

 1 #include <iostream>
 2 #include <string>
 3 using namespace std;
 4 
 5 int main()
 6 {
 7     string in{"1234"};
 8 
 9     char *cstr = const_cast<char *>(in.c_str());
10     printf("%s\n", cstr);
11 
12     int str2Int = atoi(cstr);
13     printf("%d\n", str2Int);
14 
15     return 0;
16 }
string::npos

   npos是string类的一个公有静态成员变量,定义如下:

static const size_t npos = -1;

  它主要有两个用处:

  1. 当作为成员函数参数 len 的默认数值时,表示“until the end of the string”。

  如str.substr(pos)表示截取从pos到str最末尾的字符串。

  2. 作为成员函数返回值表示没有匹配。

  如str.substr("test")若返回string::npos则表示在str中找不到test子串。