web-dev-qa-db-ja.com

C ++を使用してバイナリファイル(jpg)を文字列に読み取ります

Jpgファイルを文字列に読み込む必要があります。このファイルをサーバーにアップロードしたいのですが、APIがこの写真のデータとして文字列を必要としていることがわかりました。私が尋ねた以前の質問の提案に従いました c ++を使用してサーバーに写真をアップロードします

int main() {
    ifstream fin("cloud.jpg");
    ofstream fout("test.jpg");//for testing purpose, to see if the string is a right copy
    ostringstream ostrm;

    unsigned char tmp;
    int count = 0;
    while ( fin >> tmp ) {
        ++count;//for testing purpose
        ostrm << tmp;
    }
    string data( ostrm.str() );
    cout << count << endl;//ouput 60! Definitely not the right size
    fout << string;//only 60 bytes
    return 0;
}

なぜ60で止まるのですか? 60の奇妙な文字ですが、jpgを文字列に読み取るにはどうすればよいですか?

[〜#〜]更新[〜#〜]

ほぼそこにありますが、提案された方法を使用した後、文字列を出力ファイルに書き直すと、歪んでしまいました。 ofstream::binaryによってofstreamがバイナリモードであることも指定する必要があることを確認してください。完了!

ちなみに、ifstream::binaryios::binaryの違いは何ですか?ofstream::binaryの略語はありますか?

11
zoujyjs

ファイルをバイナリモードで開きます。そうしないと、動作がおかしくなり、少なくともWindowsでは、特定の非テキスト文字が不適切な方法で処理されます。

ifstream fin("cloud.jpg", ios::binary);

また、whileループの代わりに、ファイル全体を1回のショットで読み取ることができます。

ostrm << fin.rdbuf();
20

Jpgに0の値を含めることは合法であるため、ファイルを文字列に読み取らないでください。ただし、文字列では、値0には特別な意味があります(文字列の終わりインジケーター、別名\ 0)。代わりに、ファイルをベクターに読み込む必要があります。あなたはそうするようにこれを簡単に行うことができます:

#include <algorithm>
#include <iostream>
#include <fstream>
#include <vector>

int main(int argc, char* argv[])
{
    std::ifstream ifs("C:\\Users\\Borgleader\\Documents\\Rapptz.h");

    if(!ifs)
    {
        return -1;
    }

    std::vector<char> data = std::vector<char>(std::istreambuf_iterator<char>(ifs), std::istreambuf_iterator<char>());

    //If you really need it in a string you can initialize it the same way as the vector
    std::string data2 = std::string(std::istreambuf_iterator<char>(ifs), std::istreambuf_iterator<char>());

    std::for_each(data.begin(), data.end(), [](char c) { std::cout << c; });

    std::cin.get();
    return 0;
}
7
Borgleader

バイナリモードでファイルを開いてみてください。

ifstream fin("cloud.jpg", std::ios::binary);

推測では、あなたはおそらくWindowsと61でファイルを読み取ろうとしていましたst 文字はおそらく0x26でした-control-Z。これは(Windowsでは)ファイルの終わりを示すものとして扱われます。

前の回答 に示されているように、読み方を最適化する方法に関しては、単純さと速度のどちらかを選択することになります。

6
Jerry Coffin