質問

私は、次の文字列を持っています:

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]、私は2つの値を取得する "\ x0d \ X0A" だけではなく、 '\のx0d' が。

さらに興味深いのは、 '\ XF5' ですのmyString [6]の値、です。今回はそれがの\ x0dが存在していなかったようなものだし、正しい位置が参照されました。

私の質問は次のようになります。文字列オブジェクト:STD内の\ 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は」改行文字です。

UPDATE:それは可能であることはstd ::文字列は「\ x0dの\のX0A」は、単一の文字としてみなしので、文字列の中で一つだけの位置を占めていますか?このは「\ x0d」はstdに関して「謎」の文字がある::文字列?

追加情報: http://en.wikipedia.org/wiki/Newlineする

役に立ちましたか?

解決

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

のみ"\x0d\x0a"をLinuxで使用されているのに対し、前者と後者の変換はWindows環境では比較的一般的ですので、'\x0a'は通常、Windowsで行末に使用されたこと - 例えば、私はの行動を考えていますfopenで呼び出されたときに"wt"。私は似た何かがあなたに起こっているよね。

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

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

(異なる上、行末マーカーの詳細については、Wikipediaの記事のnoreferrer">この

他のヒント

ここで間違って起こっていることの一つは、次の行は何を期待しませんです。

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

これはC ++ std::string(const char *)にCスタイルのNULLで終わる文字列を変換するように設計されてstd::stringコンストラクタを呼び出します。このコンストラクタは、それがNULLバイト(\ X00)に達するまで、新しいstd::stringに与えられたポインタとコピーしから始まるバイトを読み取ります。これは、strlen()としてC関数の挙動と一致している。

あなたのmyStringが構築されたときに

だから、それはXFF、\ XFF、\ XFF \バイトで、長さ3の文字列で構成されています。 2より大きいインデックスへのアクセスが(せいぜいランタイムエラーを生成する、または未定義の動作で最悪)配列の末尾からバイトにアクセスしている。

std::stringは中間ヌルバイトを保持することができますが、をNULLバイトがコンストラクタに渡されたCスタイルの文字列を終了すると解釈されるので、のように文字列を初期化するために上記のコンストラクタを使用することはできません。

これは、\のX00バイトで再びあなたのコードをしようとして価値があるだろうただ、それはあなたが既に説明したものとどう違うのか確認するために、何か他のものに変更されます:

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

また、あなたが得るかを確認するには、上記のコンストラクタの後myString.length()を確認します。

おそらく、[]演算子を悪用されます。

[]演算子はCONST文字を返します。しかし、あなたはおそらくポインタとしてこれを使用したため、2つの文字を取得している - 私たちはこれを確認するために、あなたの実際のコードを参照する必要があります。

。 あなたはそのための唯一の(正しい)文字を取得している理由はおそらくですので、

は0x00は、c-文字列のヌル・ターミネータです。

あなたが取得するときに何が起こる[4]?

は、Visual Studio 2008では、\のX00は、文字列の末尾と考えられています。あなたは[5]あなたがエラーを取得するのmyStringにアクセスしようとするのでmyString.lenghtは3を返します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top