15

我需要将 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 处于二进制模式 by ofstream::binary。完毕!

ifstream::binary顺便问一下& 和有什么区别ios::binary,有什么缩写ofstream::binary吗?

4

3 回答 3

26

以二进制模式打开文件,否则会出现奇怪的行为,并且会以不适当的方式处理某些非文本字符,至少在 Windows 上是这样。

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

此外,您可以一次性读取整个文件,而不是 while 循环:

ostrm << fin.rdbuf();
于 2013-07-11T04:07:00.243 回答
10

您不应该将文件读入字符串,因为 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;
}
于 2013-07-11T04:06:47.987 回答
6

尝试以二进制模式打开文件:

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

猜测一下,您可能试图在 Windows 上读取文件,第 61 个字符可能是0x26 - 一个 control-Z,(在 Windows 上)将被视为标记文件的结尾。

至于如何最好地进行阅读,您最终会在简单性和速度之间做出选择,如上一个答案所示。

于 2013-07-11T04:07:02.070 回答