2010-12-02 12 views
0

私は学習のために "ホイールを再発明する"が好きなので、私は文字列のコンテナクラスに取り組んでいます。 NULL文字を配列ターミネーターとして使用すると(つまり、配列の最後の値はNULLになります)、nullで終了する文字列に干渉を引き起こしますか?配列内のターミネータとしてNULLを使用していますか?

空の文字列が追加された場合にのみ問題になると思いますが、何か不足している可能性があります。

EDIT:これはC++です。

+0

「干渉」とはどういう意味ですか?あなたは何を記述しているかを示すコードを投稿できますか? – SpeksETC

+0

これはCまたはC++ですか?格納している文字列はどのような型ですか? –

+0

@Sht C++。申し訳ありませんが、私はそれを明確にしませんでした。 @SpeksETC私は、文字列がnullで終わっている(私は思う?)、空の文字列は "配列の終わり"の値と同じ値を持つことを意味します。 – Maxpm

答えて

2

""は、CおよびC++では空の文字列であり、NULLではありません。 ""には、(0ではなく)ちょうど1つの要素があり、charの配列として{'\0'}と同等であることに注意してください。

vector<string> myVector; 

size_t elements(myVector.size()); 

インスタンス化:あなたはそれでありますどのように多くの値を常に知っている、あなたのコンテナクラス内の要素の数を保存する -

char const *notastring = NULL; 
char const *emptystring = ""; 

emptystring[0] == '\0'; // true 
notastring[0] == '\0'; // crashes 
+0

しかし、文字列はNULLで終了するので、空の文字列は '' "+ NULL'の値を持たないので、単に' NULL'の値ですか? – Maxpm

+2

NULLはNULと同じ値でも異なっていてもかまいません。 –

+0

'' + NULL'はありません。それは配列とポインタを追加することです(動作するかもしれませんが、意味がありません)。 '' ''には1つの要素があるので、そのアドレスは '' NULL ''にすることはできません。要素はどこかに格納する必要があります。 –

0

は、なぜあなたはvectorで使用されるパターンに従っていません。 xとの文字列。const char* x = 0;は問題があります。あなたはこれを行うときに呼び出されるビジュアルC++のSTLでこのコードを参照してください:あなたはstd::stringからコピーしているとき

_Myt& assign(const _Elem *_Ptr) 
    { // assign [_Ptr, <null>) 
    _DEBUG_POINTER(_Ptr); 
    return (assign(_Ptr, _Traits::length(_Ptr))); 
    } 

static size_t __CLRCALL_OR_CDECL length(const _Elem *_First) 
    { // find length of null-terminated string 
    return (_CSTD strlen(_First)); 
    } 
+0

私は学習目的で配列を使用しています。 – Maxpm

+0

これは、現在の有効な要素数を把握することを妨げるものではありません。 'vector'は、カバーの下に連続した(すなわち配列)ストレージも使用します。 –

+0

OPはベクトルを使用していません。なぜなら、学習目的でホイールを再現するために、指定された優先順位と競合するからです。 –

1

、イテレータbegin()end()を使用して、NULLを心配する必要はありません - 実際に、 NULLは、c_str()(この場合、このブロックの文字列を終了するためにNULLを持つブロック)を呼び出す場合にのみ存在します。memcpyを使用する場合は、data()メソッドを使用します。

2

いいえ、charの配列に格納しないので、char *の配列に格納されます。

char const* strings[] = { 
    "WTF" 
, "Am" 
, "I" 
, "Using" 
, "Char" 
, "Arrays?!" 
, 0 
}; 
+0

+1は最初にコンマを入れます。 –

2

保存する文字列の種類によって異なります。

基本的に文字配列(char*)のポインタであるCスタイルの文字列を格納している場合は、NULLのポインタ値と空の文字列の間に違いがあります。前者はポインタが「空」であることを意味し、後者は、文字値0('\0')の単一の項目を含む配列をポインタが指していることを意味します。ポインタにはまだ値があり、テストすると(if (foo[3]))、期待どおりに動作します。

格納しているものがstringのC++標準ライブラリ文字列の場合、NULLという値はありません。これはポインタがないためで、stringタイプは単一の値として扱われます。 (ポインタが技術的にはありませんが、参考として見ることができるのに対して。)この時点で

0
#include "Maxmp_crafts_fine_wheels.h" 
MaxpmContaner maxpm; 
maxpm.add("Hello"); 
maxpm.add(""); // uh oh, adding an empty string; should I worry? 
maxpm.add(0); 

、あなたのドキュメントを読んでいなかったMaxpmContainerのユーザーとして、私は次のことを期待する:

strcmp(maxpm[0],"Hello") == 0; 
*maxpm[1] == 0; 
maxpm[2] == 0; 

位置2のゼロターミネータと位置1の空の文字列との間の干渉は、 "これをメモリアドレスとして解釈する"演算子*によって回避されます。位置1はゼロになりません。これは整数になります。これをメモリアドレスとして解釈すると、ゼロになります。位置2はゼロになります。これは、メモリアドレスとして解釈すると、プログラムからの異常な無秩序な終了となります。

2

あなたは混乱していると思います。 C-ストリングは「ヌル終了」ですが、「NULL」文字はありません。 NULLは、ヌルの名前ですポインタです。 C文字列のターミネータは、ヌル文字であり、すなわち値0のバイトである。 ASCIIでは、このバイトは(やや混乱して)NULという名前です。

クラスに、文字列データの格納に使用されるcharの配列が含まれているとします。 「配列の終わりをマークする」必要はありません。配列は、コンパイル時に設定される特定のサイズを持ちます。あなたは、そのスペースのどれが実際に使用されているかを知る必要があります。文字列データのヌルターミネータがそれを実現しますが、長さを実際に記憶することでより良いパフォーマンスを得ることができます。また、静的サイズのcharバッファを持つ "string"クラスは、まったく役に立ちません。そのバッファサイズは、持つことができる文字列の長さの上限です。

したがって、より良い文字列クラスには、char*という型のポインタが含まれ、これはcharの動的に割り当てられた(new[]経由の)配列を指します。ここでも、「配列の終わりをマークする」のは意味がありませんが、文字列の長さ(つまり、使用されているスペースの量)と割り当てのサイズ(つまり、スペースの量再割り当てする前に使用することができます)。

+0

確かに、私は混乱しました。明確にしていただきありがとうございます。 – Maxpm

関連する問題