C++

2013-07-11 5 views
8

ile bir dizeye ikili dosya (jpg) oku Bir dizeye jpg dosyası okumalıyım. Bu dosyayı sunucumuza yüklemek istiyorum, sadece API'nın bu resimdeki veriler olarak bir dize gerektirdiğini öğreniyorum. Eski bir sorudaki önerileri Upload pics to a server using c++ sordum.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; 
} 

Neden 60'ta duruyor? 60 yaşında tuhaf bir karakter ve jpg'yi bir dizeye okumak için ne yapmalıyım?

GÜNCELLEME Neredeyse

ama çıkış dosyasına dize yeniden yazarken, önerilen yöntem kullanılarak sonra, bozuk. Ayrıca, akış yönünün ofstream::binary tarafından ikili modda olduğunu belirtmem gerektiğini öğrenin. Bitti! ifstream::binary & ios::binary arasındaki fark ne arada

, ofstream::binary için herhangi kısaltma var mıdır?

+2

"ifstream :: binary" ve "ios :: binary", hatta "ofstream :: binary" arasında hiçbir fark yoktur. 'ikili', tüm iostream sınıflarının kökü olan ios_base' sınıfında tanımlanır. 'ios', hiyerarşideki' ios_base' ve 'istream'/'ostream' arasında kalan bir sınıf olan basic_ios ' için bir yazım hatasıdır. Bunu kullanmak eğilimindedir çünkü yazması kolaydır. Hem "ifstream" hem de "ofstream" için ''ios :: binary '' yi kullanabilirsiniz. Hatta "ofstream" için "ifstream :: binary" ve tersini kullanabilirsiniz. –

cevap

14

Aç ikili modda dosya, ve en az Windows üzerinde uygunsuz yollarla, metin dışındaki belirli karakterleri idare edecek: Sen şöyle kolayca yapabilirsiniz.

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

Ayrıca, yerine bir süre döngü, sadece bir çekimde tüm dosyayı okuyabilir: Bir anda

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

:

ostrm << fin.rdbuf(); 
+0

güncellendi, güncellememi görün ~ – zoujyjs

6

Dosyayı bir dizeye okumamalısınız, çünkü jpg'nin 0 değerini içermesi yasaldır. Bununla birlikte, bir dizede 0 değeri özel bir anlam ifade eder (bu, dizgenin göstergesi aka \ 0'dır)). Bunun yerine dosyayı bir vektöre okumalısınız. Aksi komik davranış olacaktır,

#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 stili bir dize bir '\ 0' içermese de, bir 'std :: string' (temel olarak doğru olsanız da olabilirsiniz) bir 'std :: string' aslında ikili veriler için doğru seçim değildir). –

+0

@JerryCoffin Ancak, api bir dizge gerektirdi: 'const string & data: yüklenecek fotoğrafın ham verileri '. – zoujyjs

+0

@zoujyjs Dize nasıl başlatılacağını eklemek için kod örneğini düzenledim. Vektörle aynı şekilde çalışır. – Borgleader

6

ikili modda dosyayı açmayı deneyin sanırım, muhtemelen dosyayı Windows üzerinde okumaya çalışmıştınız ve 61 st karakteri muhtemelen 0x26 idi - bir kontrol-Z, (Windows'ta) dosyanın sonuna işaretlenecek .

Okuma en iyi şekilde nasıl yapılacağı konusunda, a previous answer'da gösterildiği gibi basitlik ve hız arasında seçim yapabilirsiniz.

+0

Çalışıyor, güncellememi görün. – zoujyjs