2

通常の ifstream と現在使用している boost:iostream の両方で次のコードを試しましたが、どちらも同じ結果になりました。

これは、ファイルを physfs からメモリにロードし、それをハンドラーに渡して処理することを目的としています (画像、オーディオ、データなど)。現在、c_str が呼び出されると、ファイルのごく一部しか返されません。

        PhysFS::FileStream file("Resources/test.png" , PhysFS::OM_READ);

    if(file.is_open()) {

        String* theFile;

        theFile = new String((std::istreambuf_iterator<char>(file)), 
        std::istreambuf_iterator<char>());

        String::iterator it;
        for ( it=theFile->begin() ; it < theFile->end(); it++ ) {
            std::cout << *it; 
        } // Outputs the entire file

        std::cout << theFile->c_str(); // Outputs only the first few lines

    }

イテレータ ループは期待どおりに png ファイル全体を出力しますが、c_str 呼び出しは最初の数文字 (\211PNG) のみを返します。

私はかなり長い間、このコードのバリエーションを試してきましたが、成功しませんでした。何か案は?

4

3 に答える 3

15

次の文字はヌル (ASCII 0) バイトだと思います。c_str() は単に *char を提供するため、stdout への書き込みは、最初の null バイトで終わるクラス C 文字列として解釈されます。

この文字列への C ライクなインターフェイスが本当に必要な場合、主なことは、theFile->c_str() がデータを指し、theFile.length が文字列内の文字数を示すことです。したがって、次のようなことをしたいかもしれません:

char *c_value = theFile->c_str()
for (int i = 0; i < theFile.length; i++)
{
   cout << c_value[i];
}

実際の解決策は、最初に char * に変換する理由によって異なります。char * のみを受け入れるレガシー関数を呼び出している場合、そのレガシー関数には長さの引数もある可能性があります。

于 2009-10-12T16:59:16.147 に答える
2

バイトの 1 つはおそらく 0 です。つまり、char* (c_str は) を渡すときに cout への文字列の終わりを意味します。

于 2009-10-12T16:59:53.617 に答える
2

std::vector<unsigned char>これの代わりに使用することを検討しstd::stringます。ベクター内のバイナリ データを扱う方がはるかに簡単です。C スタイルの配列&vec[0]にアクセスする必要がある場合は、基になるポインターを参照できます。また、ファイルの抽象化がフードの下のファイルモードにも使用されるようにします。std::ios_base::binary

于 2009-10-12T17:28:11.173 に答える