2009-09-02 17 views
-1

I次の文字列があります。のstd ::文字列の文字参照

index          0 1 2 3 4 5 6 7 
std::string myString with the content of "\xff\xff\xff\x00\xff\x0d\x0a\xf5" 

私はのmyStringに参照のうえだ[3]、私が期待される '\ X00' の値を取得します。

しかし、私がmyString [5]を参照しているときは、\ x0dの代わりに2つの値 "\ x0d \ x0a"を取得します。

さらに興味深いのは、myString [6]の値です。これは '\ xf5'です。今回は\ x0dが存在せず、正しい位置が参照されたようです。

私の質問は、次のようなものです。std:stringオブジェクトの\ x0d文字はどういう意味がありますか?インデックス作成時にどのようにスキップされますか?それは、この方法を数えるようなものだ:コメントとして

index      0 1 2 3 4 5 5 6 
std::string myString = "\xff\xff\xff\x00\xff\x0d\x0a\xf5" 

、「\ x0d」文字は、13 ASCII文字「キャリッジ・リターン」とは「\ X0Aは」改行文字です。

更新:std :: stringは "\ x0d \ x0a"を1文字と見なすことができるため、文字列の1つの位置だけを占有することはできますか?この '\ x0d'はstd :: stringに関して「謎の」文字ですか?

ADDITIONAL INFO:http://en.wikipedia.org/wiki/Newline

+5

を読み取るためのhttp://www.cplusplus.com/reference/string/string/string/あなたは小さな、完全な、コンパイルプログラムでこれを示していることはできますか?私はインデックス5にアクセスするときに2文字をどのように取得するのか分かりません。 '[] '演算子は結局、1つの' char'を返します。 – sbi

+0

は\ x0改行ですか?これらは単一の文字として扱われて、改行スタイルが異なるシステム上で同じ行数の索引を保持するようにすることができますが、std :: stringの内部動作については実際には分かりませんが、私は答えとして投稿しません。 –

+0

私は引き続きこの質問に情報を追加します。確かにあなたの感心は正しいかもしれません: '\ x0a'は改行で、std :: stringはそれらを '\ x0d \ x0a'のように扱います。 – citn

答えて

9

は、あなたがこのstd::stringで起こっていますか? std::string::operator[]const char &を返すので、どのように2つの文字('\x0d''\x0a')を返すことができますか?

つまり、"\x0d\x0a"は通常、Windowsでは行末に使用されますが、Linuxでは'\x0a'しか使用されないため、前者の変換はWindowsでは比較的一般的です。たとえば、私はその動作を考えています"wt"で呼び出された場合はfopenです。私はあなたに似たようなことが起こっていると思います。

:元の質問に対するあなたのコメントに基づいて、私は何が起こっているのか推測できると思います。

あなたの文字列には、それが含まれていると思われる内容は含まれていないと思います。文字列をファイルに出力するために使用しているメカニズム(たぶんofstream?)が行末の翻訳を行っているので、誤解されています。これは、'\n'(Unixの行末コード)が'\r\n'(Windowsの行末コード)に変換されていることを意味します。行末変換の目的は、オペレーティングシステム間でコードをより移植性の高いものにすることです。バイナリモードのファイルをで開くことで禁止することができます。 ofstreamの場合、これはファイルを開くときにios_base::binaryフラグを指定することによって行われますが、このフラグはデフォルトでは設定されていません。

(異なるオペレーティングシステム上の行末マーカーの詳細については、このWikipedia articleを参照してください。)

これは、私が起こっていると考えているものです。そのための行末翻訳はmyString[5]'\x0a''\x0d\x0a'として出力されている、上記expalined、および

ofstream file("myfile.txt"); 
for(size_t i=0; i<myString.size(); i++) 
    ofstream << myString[i]; 

:あなたの文字列が実際に

index     0 1 2 3 4 5 6 
myString contents "\xff\xff\xff\x00\xff\x0a\xf5" 

が含まれているあなたはそれをこのような何かを出力していますそれがあなたを混乱させています。

+0

実際、私は同様のメカニズムを使用しています:std :: ostringstream。また、将来の参考のためにこの翻訳に関する情報を追加することができれば、私は感謝します。たとえば、誰が実際にそれを行いますか、そしておそらくウェブ上のいくつかのリンクです。 – citn

+0

包括的なWikipediaの記事へのリンクを追加しました。実際に行末の翻訳がどこで行われるかに関しては、おそらく標準的なライブラリの実装に依存しますが、おそらく 'ofstream' /' ostringstream'やその基本クラスの1つで起こります。 –

0

[]演算子を誤って使用している可能性があります。

[]演算子はconst charを返します。しかし、おそらくポインタとしてこれを使用しているので、2文字を取得しています - 実際のコードを確認する必要があります。

0x00はC文字列のヌルターミネータであるため、おそらく1文字しか表示されないのです。

[4]になるとどうなりますか?

0

Visual Studio 2008では、\ x00は文字列の最後とみなされます。したがって、myString.lenghtは3を返します。myString [5]にアクセスしようとすると、エラーが発生します。

9

ここで間違って起こっているの一つは、あなたが期待する何をしません次の行である:これはにCスタイルのNULLで終わる文字列を変換するように設計されてstd::string(const char *)コンストラクタを呼び出し、

std::string myString = "\xff\xff\xff\x00\xff\x0d\x0a\xf5"; 

C++ std::string。このコンストラクタは、指定されたポインタから始まるバイトを読み取り、NULLバイト(\ x00)に達するまで新しいstd::stringにコピーします。これは、strlen()などのC関数の動作と一致しています。

したがって、myStringが構築されると、それは長さ3の文字列で構成され、バイトは\ xff、\ xff、\ xffです。 2より大きいインデックスへのアクセスは、配列の最後からバイトにアクセスしています(実行時にエラーが発生するか、最悪の場合は未定義の動作になります)。 std::stringは中間NULLバイトを保持することができますが、あなたはがnullバイトは、コンストラクタに渡されたCスタイルの文字列を終了すると解釈されるので、このような文字列を初期化するために上記のコンストラクタを使用しないことを

注意。

の\ X00バイトがちょうどそれはあなたが既に説明したものとどう違うのか確認するために、何か他のものに変更してそれは再びあなたのコードを試してみる価値のようになります。

std::string myString = "\xff\xff\xff\x01\xff\x0d\x0a\xf5" 

また、上記のコンストラクタの後myString.length()をチェックあなたが得るものを見る。 string(char const *)

それはNULがC文字列を終了受け取り:

+0

O.K.つまり、std :: string :: string(const char *)ctorは、 '\ 0'までC文字列を反復処理します。なぜ私がMSVCでの行動を見ていたのかが分かります。私の悪い... – Abhay

+0

良い点 - 私はcmdevが文字列の内容を表示したいと思っていて、実際に文字列を初期化するために使用されているコードを与えていなかったと思いますが、これが実際の初期化あなたは問題を釘付けにしました。 –

+0

それは正しいです。私が見せたいのは、文字列の内容だけでした。正確な割り当ては、この単純な割り当てよりはるかに複雑です。私はそれにコメントを追加します。 – citn

2

は、次のコンストラクタを持つ文字列を作成します。したがって、最初の0文字に従って長さが求められます。

あなたはサイズを指定し、他のコンストラクタを使用する必要があります呼び出すことによってstring(char const *,size_t n)を:

std::string myString("\xff\xff\xff\x00\xff\x0d\x0a\xf5",8); 

はさらに

関連する問題