C风格字符串
C风格字符串特指在C语言中字符串的存储方式。 在编程语言中,常常需要表示一段字符,如“今天你吃了么”,“how are you?”,“afjsa234234(*&(*(”等等。同一种字符串的写法在不同的编程语言中表示的字面值都是一样的,即引号中间的内容,但是在存储的处理上往往不一样。
C语言中字符串的处理
在C语言中,字符串是以字符数组的形式进行存储的,且在数组中以'\0'作为终结符。由于'\0'在ASCII中表示空字符(NULL),即在语意上不可能有有效字符与之重复,故用其来表示字符串的结尾至少在ASCII编码下是合理的。
C++中字符串的处理
在C++语言中,除了继承了C语言中的这种字符串表达形式外,还新添了string类用来表达字符串。就表义来说,这两种字符串存储方式是等价的,但在处理的过程中却有显著的区别。在string类中,所有的对字符串的操作都被封装为成员函数,因此只要string内部有统一的约定,可以不在使用'\0'作为结尾标志。但对于C语言中的字符串,所有的操作都是来源于<cstring>中的以str开头的函数,这些函数的特点就是都以'\0'作为所处理的字符串的结尾标志。
由于这些显著的特点,为了区分C++中这两种不同的字符串,使用“C风格字符串”来特指来源于C语言的字符串存储方式。
与编码规范的冲突
ASCII编码及其扩充规范中,每个字符长度都不超过1Byte,因此,在C风格字符串中用'\0'表示结尾是合法的。但在UTF16编码中,每个字符使用2Byte进行编码,故会出现其中一个字符为0x00的情况,此时如果仍使用C风格字符串,则在使用相关函数进行处理时,会在第一个0x00出现的位置就被认为是字符串已经结束,但其实字符串并不在此处终结。
UTF8是一种很好的解决方案,UTF8中字符的编码非定长,可能是1Byte或者是2Byte,但是这种编码方案中用每个字符的前缀来表示当前字符的长度,因此既有足够的空间来存储较多的字符,又不会出现0x00导致字符串在被以C风格字符串处理时异常结束。