2013-07-11 156 views
8

我需要將jpg文件讀取到字符串。我想上傳這個文件到我們的服務器,我只是發現API需要一個字符串作爲這張圖的數據。我在前一個問題中遵循了這些建議,我詢問了Upload pics to a server using c++使用C++讀取二進制文件(jpg)爲字符串

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?

UPDATE

快到了,但使用建議的方法,當我重寫字符串輸出文件後,它扭曲了。找出我應該指定的流是由二進制模式ofstream::binary。完成!

順便說一句ifstream::binary & ios::binary有什麼區別,有沒有ofstream::binary的縮寫?

+2

'ifstream :: binary'和'ios :: binary',甚至'ofstream :: binary'之間沒有區別。 'binary'在'ios_base'類中定義,它是所有iostream類的根。 'ios'是'basic_ios '的一個typedef,它是一個落在層次結構中'ios_base'和'istream' /'ostream'之間的類。我傾向於使用它,因爲它很容易輸入。你可以在'ifstream'和'ofstream'中使用'ios :: binary'。你甚至可以用'ifstream :: binary'作爲'ofstream',反之亦然。 –

回答

14

以二進制方式打開文件,否則將有滑稽的行爲,它會處理不當的方式,至少在Windows上某些非文本字符。

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

此外,而不是一個while循環,你可以直接讀取整個文件中一個鏡頭:

ostrm << fin.rdbuf(); 
+0

已更新,請參閱我的更新〜 – zoujyjs

6

您不應將文件讀取到字符串,因爲它對於包含值爲0的jpg是合法的。但是在字符串中,值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; 
} 
+1

雖然C風格的字符串不能包含'\ 0',但是'std :: string'可以(儘管你基本上是正確的 - 一個'std :: string'實際上不是二進制數據的正確選擇)。 –

+0

@JerryCoffin但是api需要一個字符串:'const string&data:要上傳的照片的原始數據.' – zoujyjs

+0

@zoujyjs我編輯了代碼示例以包括如何初始化字符串。它與矢量的工作方式相同。 – Borgleader

6

嘗試打開該文件以二進制方式:

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

在猜測,你可能試圖讀取Windows上的文件,並且字符可能是0x26 - 一個控制-Z,它(在Windows上)將被視爲標記文件的結尾。

就如何最好地進行閱讀而言,您最終可以在簡單性和速度之間進行選擇,如a previous answer中所示。

+0

它的工作原理,請參閱我的更新。 – zoujyjs