C++学習ノート(二)Cスタイル文字列とstringクラスの違いと連絡

5949 ワード

一、概説
時には文字列を使う時、いつもC++の文字列のタイプとC風格の文字列を混同して、あるいは独立して異なる概念で、そのために特定の資料を探して、両者の間の区別と連絡を総括します.誤りがあればご指摘願います.
二、C言語の文字列
C言語では、文字列の処理は主に文字配列(空文字'0'で終わる)または文字タイプへのポインタ、すなわちchar*を用いるが、ポインタは文字列タイプを実現するのに面倒である.
//example 1
char str[15]="Hello world!"; //      ,    char str[] ="Hello world!";  
*(str+2)=’L’;   //  *()           3   
char *p= str;    //    p    str    
*(p+2)=’L’;    //        str  3   

char *ptr ="Hello world!";  //           ;
*(ptr+2)='L';             //  ,     ,          3   

これは、第1の文字列が配列strによって開かれ、配列の各値は変更可能な変数であり、第2のポインタptrは文字列定数を指し、文字列定数は変更できないため、誤判を避けるために文字列定数を指す場合にconstポインタを使用するべきである.
const char*ptr=「Hello world!」
//example 2
char *ptr = new char[15];   // new      15 char   ,ptr        
ptr = "abcdefg";           //  ,    ptr           
ptr[0]='A';                //  ptr[  ] *(ptr+  )     ,            
*ptr ='a';                 //   ptr[0]  

スタック割り当てメモリであるため、関数呼び出しが終了した後、自分で取り消すことはないため、関数にdelete[]ptrを加える必要がある.文.
三、C++の文字列
Cスタイルの文字列は複雑で、大きなプログラムの開発に適していないため、C++標準ライブラリはstringクラスを定義し、ヘッダファイル形式は#includeであり、ヘッダファイルはエラーであり、この2つのヘッダファイルは主にstrlen()、strcpy()などのCスタイル文字列を処理する方法を定義します.1つ目はCのヘッダファイル形式、2つ目はC++のCスタイルヘッダファイルです.
まずsting類の原形を見てみましょう.
//example 3
class String
{
public:
	String(const char *str = NULL);//       
	String(const String &other); //      
	~ String(void); //    
	String & operator =(const String &other);//    
private:
	char *m_data;//        
};
//      
String::String(const char *str)
{
	if(str==NULL)
	{
		m_data = new char[1]; //                '\0' //   : m_data NULL   
		*m_data = '\0';
	}
	else
	{
		int length = strlen(str);
		m_data = new char[length+1]; //     NULL      
		strcpy(m_data, str);
	}
}
// String     
String::~String(void)
{
	delete[] m_data; //  delete m_data;
}
//      
String::String(const String &other) //      const 
{
	int length = strlen(other.m_data);
	m_data = new char[length+1]; // m_data NULL   
	strcpy(m_data, other.m_data);
}
//    
String & String::operator =(const String &other) //      const 
{
	if(this == &other) //     
		return *this;
	delete[] m_data; //         
	int length = strlen( other.m_data );
	m_data = new char[length+1]; // m_data NULL   
	strcpy( m_data, other.m_data );
	return *this; //        
}

stringクラスにはプライベートポインタchar*m_が含まれていると考えられます.dataは、コンストラクション関数とコピーコンストラクション関数によってnewで空間を開き、strcpyで転送された文字列(Cスタイルまたはstringクラスオブジェクト)をコピーし、コンストラクション関数によってメモリを解放します.
(1)stringクラスのコンストラクション関数とコンストラクション関数は以下の通りである.
a) strings;//空の文字列を生成するs
b)strings(str)/コピー構造関数strのレプリカを生成し、strはstringクラスのオブジェクトである
c)strings(str,stridx)/文字列str内の「位置stridxから始まる」部分を文字列の初期値とする
d)strings(str,stridx,strlen)/文字列str内の「stridxから始まり、長さが最も多いstrlen」の部分を文字列の初期値とする
e)strings(cstr)/Cスタイル文字列をsの初期値とする
f)string s(chars,chars_len)/Cスタイル文字列の前chars_len文字は文字列sの初期値として使用されます.
g)strings(num,c)/num個のc文字を含む文字列を生成し、cは文字型である
h)strings(beg,end)/区間beg;end(endを含まない)内の文字を文字列sの初期値とする
i)s.~string()/すべての文字を破棄し、メモリを解放する
 
(2)文字列操作関数
a)=,assign()/新しい値を与える
b)swap()/二つの文字列の内容を交換する
c)+=,append(),push_back()/末尾に文字を追加
d)insert()/挿入文字
e)erase()/削除文字
f)clear()/すべての文字を削除
g)replace()/置換文字
h)+//直列文字列
i)==,!=,<,<=,>,>=,compare()/比較文字列
j)size()、length()/戻り文字数
k)max_size()/戻り文字の最大個数
l)empty()/文字列が空であるか否かを判断する
m)capacity()/再割り当て前の文字容量を返す
n)reserve()/一定量のメモリを保持して一定数の文字を収容する
o)[],at(//アクセス単一文字
p)>>,getline()/streamから値を読み込む
q)r)copy()/ある値をC_に割り当てるstring
s)c_str()/内容をC_string戻り
t)data()/コンテンツを文字配列で返す
u)substr()/サブ文字列を返す
v)検索関数
w)begin()end()/STLのような反復器サポートを提供
x)rbegin()rend()/逆反復器
y)get_allocator()/戻りコンフィギュレータ
これらのメンバー関数はstring文字列の操作に大きな便利さをもたらした.
(3)要素の読み書き
//example 4
string str("abcdefg");     //         str
str[0] = 'A';             //      ,      
str.at(0)='A';            //      at()      

ただし、下付き文字を使用すると境界を越えると例外は報告されず、at()を使用すると例外が報告されます.str.length()関数で文字列長(空の文字を含まない)が得られると、forループ配列を使用できます.もう1つの方法は反復器を使用します.
	//example 5
	string s = "abcdefg";
	for(string::iterator iter = s.begin(); iter!=s.end(); iter++)    //    
	{
		cout<<*iter<<endl;
	}
	for(string::reverse_iterator iter = s.rbegin(); iter!=s.rend(); iter++)    //    
	{
		cout<<*iter<<endl;
	}

stringクラスには、ポインタ操作と同様に、反復器が範囲をチェックしない反復器iteratorがあります.反復器は各文字にアクセスする構文を提供します.
string::iteratorまたはstring::const_iteratorは反復変数を宣言し、const_iteratorは反復の内容を変更することを許さない.一般的な反復関数は次のとおりです.
const_iterator begin()const;
iteratorbegin();//stringの先頭に戻る
const_iterator end()const;
iteratorend();//stringの最後の文字の後ろの位置を返します
const_iterator rbegin()const;
iteratorrbegin();//stringの最後の文字の位置を返す
const_iterator rend()const;
iteratorrend();//stringの最初の文字位置を返す前のrbeginとrendは、反復アクセスのために使用され、反復器string::reverse_を設定します.iterator,string::const_reverse_iterator実装
四、Cスタイル文字列とstringクラスの変換
C++が提供するC++文字列から対応するCスタイル文字列を得る方法はdata()、c_str()とcopy(),Cスタイル文字列をstringに変換するには構造関数でよい.
	//example 6
	string var = "abcdefg";
	const char *p = var.c_str();    //  const    ,p            

	string str = "abcdefg";
	char p[10];
	strcpy(p,str.c_str());
	p[0] ='A';                  //  p   10  , p        

	char *p = new char[str.length()+1];
	strcpy(p ,str.data());
	delete []p;                  //  data()  

	char  p[10];
	str.copy(p,7);
	p[str.length()+1]='\0';         //  copy  

data()は文字配列で文字列の内容を返しますが、'0'は追加されません.c_str()は「0」で終わる文字配列を返し、copy()は文字列の内容を既存のc_にコピーまたは書き込むstringまたは文字配列内.