// Last Update:2015-10-22 15:36:27
/**
* @file str1.cpp
* @brief this is a test for string;
* @author renzezhong
* @version 0.1.00
* @date 2015-10-22
*/
/* 由于没有分析过string 的源代码,现在只描述现象,并作出个人推测,想细致了解的朋友可以自行查找string 源代码。
*现象:
*string 类使用有很多需要注意的地方,在一个项目中发现string 构造出现错误,使用的string 构造函数版本是string s((const) char* , (const)int , (const)int);( const 可能有也可能没有,个人认为有)
*期望通过该构造函数将buf中length长度的内容拷贝到s中,但是由于buf中在某个位置(除了尾部)存在'\0'字符,导致buf中length个字节的内容并没有全部拷贝到s中,而是读到'\0'为止,造成内容的丢失。
*其实现的效果等同与使用s.assign(cp)(cp是char *类型的指针)//用cp所指向的以空字符结束的字符串副本替换s.
*
*以下结合测试用例来推测...只是推测啊...但是现象还是可以看到的。
*/
#include <string>
#include <iostream>
using namespace std;
int main(void){
char a [6]= {'0', '1', '2', '\0', '4', '5'};
//版本一(推荐的版本):string (cp, n) 创建一个string对象,它被初始化为cp所指向数组的前n个元素的副本。注意这里说的是数组,数组和字符串有很大不同,就是数组中可以存储'\0'.
cout << "string str(a, 6)" << endl;
string str(a, 6);
cout << str[4] << ' ' << str[5]<< endl;//4 5
cout << str << endl;//01245
//版本二(程序中出错的版本):string(const char *, int, int)这个版本的初始化在c++primer 中并没有出现过,但是可以使用不报错,个人推测是在string实例化时,调用了string s(string s2, int pos2, int len2) 版本//创建一个string对象,它被初始化为s2中从下标pos2开始的len2个字符的副本,如果pos2 > s2.size()则操作无效。 根据我所掌握的知识来推测,由于string被泛化过,所以string在实例化时有类似于模板实例化的隐式类型推断能力,具体来说:发现参数1是一个char*,而string 提供的三参构造函数中,没有对应版本,但是有一个三参版本中参数1是string,而string 有一个string s(const char* cp)的构造版本//创建一个string 对象,它被初始化为cp所指向的以空字符结束的字符串的副本,所以就调用这个构造函数先将参数一进行隐式类型转换,再调用版本2。 虽然参数3指定了要拷贝的长度,但是实际上只拷贝到buf中‘\0’前('\0'出现的位置在length指定的位置前),因此导致内容丢失。
cout << "string str(a, 0, 6)" << endl;
string str1(a, 0, 6);//效果等同于s.assign(cp)以cp所指向的以空字符结束的字符串副本替换s
cout << str1[4] << ' ' << str1[5]<< endl;//4 5
cout << str1 << endl;//01245
//现在使用的版本:string (~::iterator p, ~:: iterator b, ~:: iterator e)//在迭代器p指向的元素之前插入迭代器b和迭代器e标记范围内所有的元素返回void.
cout << "string str(str2.begin(), a, a+6)" << endl;
string str2;
str2.insert(str2.begin(), a, a+6);//在c++primer中并没有提供一个string(string::iterator p, char*, char*),但是考虑到迭代器底层封装的就是指针,所以推测进行了隐式类型转换也说的过去。
cout << str2[4] << ' ' << str2[5]<< endl;//4 5
cout << str2 << endl;//01245
}
/*
*所以个人建议:不要轻易使用那些没有被明确定义过的版本,c++ primer 中列出的实例化方式非常多,相信够用...
* */
/**
* @file str1.cpp
* @brief this is a test for string;
* @author renzezhong
* @version 0.1.00
* @date 2015-10-22
*/
/* 由于没有分析过string 的源代码,现在只描述现象,并作出个人推测,想细致了解的朋友可以自行查找string 源代码。
*现象:
*string 类使用有很多需要注意的地方,在一个项目中发现string 构造出现错误,使用的string 构造函数版本是string s((const) char* , (const)int , (const)int);( const 可能有也可能没有,个人认为有)
*期望通过该构造函数将buf中length长度的内容拷贝到s中,但是由于buf中在某个位置(除了尾部)存在'\0'字符,导致buf中length个字节的内容并没有全部拷贝到s中,而是读到'\0'为止,造成内容的丢失。
*其实现的效果等同与使用s.assign(cp)(cp是char *类型的指针)//用cp所指向的以空字符结束的字符串副本替换s.
*
*以下结合测试用例来推测...只是推测啊...但是现象还是可以看到的。
*/
#include <string>
#include <iostream>
using namespace std;
int main(void){
char a [6]= {'0', '1', '2', '\0', '4', '5'};
//版本一(推荐的版本):string (cp, n) 创建一个string对象,它被初始化为cp所指向数组的前n个元素的副本。注意这里说的是数组,数组和字符串有很大不同,就是数组中可以存储'\0'.
cout << "string str(a, 6)" << endl;
string str(a, 6);
cout << str[4] << ' ' << str[5]<< endl;//4 5
cout << str << endl;//01245
//版本二(程序中出错的版本):string(const char *, int, int)这个版本的初始化在c++primer 中并没有出现过,但是可以使用不报错,个人推测是在string实例化时,调用了string s(string s2, int pos2, int len2) 版本//创建一个string对象,它被初始化为s2中从下标pos2开始的len2个字符的副本,如果pos2 > s2.size()则操作无效。 根据我所掌握的知识来推测,由于string被泛化过,所以string在实例化时有类似于模板实例化的隐式类型推断能力,具体来说:发现参数1是一个char*,而string 提供的三参构造函数中,没有对应版本,但是有一个三参版本中参数1是string,而string 有一个string s(const char* cp)的构造版本//创建一个string 对象,它被初始化为cp所指向的以空字符结束的字符串的副本,所以就调用这个构造函数先将参数一进行隐式类型转换,再调用版本2。 虽然参数3指定了要拷贝的长度,但是实际上只拷贝到buf中‘\0’前('\0'出现的位置在length指定的位置前),因此导致内容丢失。
cout << "string str(a, 0, 6)" << endl;
string str1(a, 0, 6);//效果等同于s.assign(cp)以cp所指向的以空字符结束的字符串副本替换s
cout << str1[4] << ' ' << str1[5]<< endl;//4 5
cout << str1 << endl;//01245
//现在使用的版本:string (~::iterator p, ~:: iterator b, ~:: iterator e)//在迭代器p指向的元素之前插入迭代器b和迭代器e标记范围内所有的元素返回void.
cout << "string str(str2.begin(), a, a+6)" << endl;
string str2;
str2.insert(str2.begin(), a, a+6);//在c++primer中并没有提供一个string(string::iterator p, char*, char*),但是考虑到迭代器底层封装的就是指针,所以推测进行了隐式类型转换也说的过去。
cout << str2[4] << ' ' << str2[5]<< endl;//4 5
cout << str2 << endl;//01245
}
/*
*所以个人建议:不要轻易使用那些没有被明确定义过的版本,c++ primer 中列出的实例化方式非常多,相信够用...
* */