//为了方便,要包含的文件会不同,但我没有删
#include <iostream>
#include <string>
#include <vector>
#include <bitset>
#include <cstring> //和C语言的string.h其实是一个版本
using std::bitset;
using std::vector;
using std::cin;
using std::endl;
using std::cout;
using std::string;
//---------------------------------------------------------------------------
int main()
{
//读入string,并存入vector中
vector<string> svec;
string s;
while(cin>>s)
svec.push_back (s);
//把vector中的内的string复制给字符指针数组,每个string对象要有一个新字符数组
//在下面的各个方法中,最重要的strcpy方法,不用这个,而
char **ca=new char*[svec.size()]; //动态分配指针数组时要写char*[...],而不能写*char[...],否则会报错,这里建的是一个指针的数组,其中
//每个指针都指向一个字符数组,这里概念有点绕,要注意了
//~~~~~~~~~~~~~~~~~~~~复制字符串方法四:用string作过度也是可以的~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
size_t ss=0;
for(;ss!=svec.size ();++ss)
{
string str=svec[ss];
char *p=new char[str.size ()+1];
//如果不用strcpy的方法,而用这样的句子p=str.c_str(),则会出现运行时的错误,因为c_str()方法反回的是一个常量这符串
//指针,const char*,而p是一个char*,即使把p,ca都设为const,也只能通过编绎,运行时还是会出错,
//因为当用new分配内存时得到新内存空间,p是一个指向该空间的指针,而当我们用string str时,str会有一个新的内存空间,这个
//空间的指针地址也是不变的,因此以此进行循环时,str内的内容在不断改变,而p所指的也是这不断改变内容的同一地址
//而ca[ss]也指向了这个内容,但这个str所代表的内容又会随着for的结束被清掉,因此是没有用的
//也可以试着把str放在循环外也一样,因为p代表的存储区内是空的
//所以一定要strcpy的方法,把字符串复制到新分配的存储区,再怎么做,都会是对的
strcpy(p,str.c_str ());
ca[ss]=p;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`
//__________________________________复制字符串方法一:用下标___________________________________________________________--
// for(size_t ss=0;ss!=svec.size ();++ss)
// {
// ca[ss]=new char[svec[ss].size ()+1]; //直接用ca[ss]作为被赋值对象,也能正确运行
// //ca[s]本身为一个指向字符的指针,和new char[]的反回类型是一致的,所以只需要用这个就好;
// //在这个循环中,使ca[0],ca[1],ca[2],ca[..]分别指向自由存储区的与vector中string对应大小的空间;
//strcpy(ca[ss],svec[ss].c_str ());
//
// //由于c_str()反回的是const char*型指针,所以把前面的ca改为const char**型了,指向常量的指针了
// }
//_________________________________________________________________________________________________________________________________--
//-------------------复制字符串方法二:以下为采用svec的大小作为边值进行循环的方式,用下标取vector内的string-----------------------------
//for(size_t ss=0;ss!=svec.size ();++ss)
//{
//
//
// char *p=new char[svec[ss].size ()+1]; //没有p这个指针,而直接用ca[ss]作为被赋值对象,会出现错误
// //ca[s]本身为一个指向字符的指针,和new char[]的反回类型是一致的,所以只需要用这个就好;
// //在这个循环中,使ca[0],ca[1],ca[2],ca[..]分别指向自由存储区的与vector中string对应大小的空间;
// strcpy(p,svec[ss].c_str ());
//
// ca[ss]=p;
//
// //由于c_str()反回的是const char*型指针,所以把前面的ca改为const char**型了,指向常量的指针了
//
//
//}
//
//-------------------------------------------------------------------------------------------------------------------------
//==========================复制字符串方法三:以下为采用vector的iterator指针循环的方式,进行分配内存,并复制字符串=============================
/*size_t ix=0;
for(vector<string>::iterator ite=svec.begin ();ite!=svec.end ();++ite,++ix)
{
char *p=new char[(*ite).size ()+1];
strcpy(p,(*ite).c_str ());
ca[ix]=p;
}*/
//===================================================================================================================================
//输出vector对象的内容
cout<<"vector中的内容为:";
for(vector<string>::iterator ite=svec.begin ();ite!=svec.end ();++ite)
cout<<*ite<<"/40";
cout<<endl;
//输出新字符数组中的内容
cout<<"现输出字符数组中的内容:"<<endl;
//for(size_t s=0;s!=svec.size ();++s)
for(size_t s=0;s!=3;++s)
{
cout<<"字符数组"<<s<<"中的字符有:";
for(size_t s1=0;s1!=strlen(ca[s]);++s1)
cout<<ca[s][s1]<<"/40";
cout<<endl;
}
//需要delete用new建的对象
for(size_t s=0;s!=svec.size ();++s)
delete [] ca[s];
delete []ca;
return 0;
}
/*
122页习题4.34和4.35:从vector中复制字符串到字符指针数组中,并输出结果
*/