Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Проблемы с чтением бинарного файла (jpg)


Автор: php5 13.8.2013, 17:04
Нужно  прочитать содержание бинарного файла в  частности  рисунок  в jpg
Для этого написал функцию 
Код

char* readFile(string file) {
    string str = "";
    char* buf; 
        ifstream f(file.c_str(),ios_base::in|ios_base::binary|ios::ate);
    if (f.is_open() && f.good()) {
           long size = f.tellg();
           f.seekg(0, ios::beg);
       buf = new char[size];
       memset(buf, 0, size);
       f.read(buf, size);
       f.close();
    }
    return buf;
}  

Но на выходе почему то получаю  строку  яШяб3эExif  хотя если попытаться прочитать данной функцией текстовый файл то все ок 

Автор: SenkraD 13.8.2013, 17:26
дебагер читает ее как С-строку, тоесть при первом \0 обрывает показ, а по сему тебе необходимо еще и size возвращать чтобы можно было работать дальше или использовать std::vector<unsigned char> или std::string, если у тебя С++11, если нет, то возвращать их будет накладно, а по сему придется передавать по ссылке, хотя можно и так замутить std::vector const& read(std::string, std::vector)

Автор: php5 13.8.2013, 21:15
Ну  вроде бы  получилось  прочитать весь файл 
Код

char* readFile(string file) {
    char* buf; 
    ifstream f(file.c_str(),ios_base::in|ios_base::binary|ios::ate);
    if (f.is_open() && f.good()) {
        vector<char> data(f.tellg());
      f.seekg(0, ios::beg);
        f.read(&data[0], data.size());
      f.close();
    }    
    return buf; 
} 

Теперь возникает вопрос  как  vector<char>  преоброзовать в char*  дабы можно было  сохранит 
Код

void save(char* buf) {    
    FILE *file;
    char* file_name = "D:\\img.jpg";
    file = fopen(file_name, "wb"); 
    fputs(buf, file);
    fclose(file);
}


Автор: SenkraD 13.8.2013, 23:01
собсвенно как-то так:
Код

#include <vector>
#include <fstream>


std::vector<char>& load_file(std::string const& filename, std::vector<char>& buffer)
{
    buffer.clear();
    
    std::ifstream file(filename.c_str(), std::ios::binary);
    if (file.bad())
    {
        return buffer;
    }

    char symbol;
    buffer.reserve(static_cast<std::string::size_type>(file.rdbuf()->in_avail()));
    while (file.get(symbol))
    {
        if (buffer.capacity() == buffer.size())
        {
            buffer.reserve(buffer.capacity() * 3);
        }
        buffer.push_back(symbol);
    }

    return buffer;
}

void save_file(std::string const& filename, std::vector<char> const& buffer)
{
    std::ofstream file(filename.c_str(), std::ios::binary | std::ios::trunc);
    if (file)
    {
        file.write(&buffer[0], buffer.size());
    }
}


или можно сделать более лаконично на std::copy, стримовых итерараторах и std::back_inserter
Код

#include <vector>
#include <fstream>
#include <iterator>
#include <algorithm>

std::vector<char>& load_file(std::string const& filename, std::vector<char>& buffer)
{
    std::ifstream file(filename.c_str(), std::ios::binary);

    buffer.clear();
    buffer.reserve(static_cast<std::string::size_type>(file.rdbuf()->in_avail()));
    std::copy(
          std::istream_iterator<char>(file)
        , std::istream_iterator<char>()
        , std::back_inserter(buffer)
    );

    return buffer;
}

void save_file(std::string const& filename, std::vector<char> const& buffer)
{
    std::ofstream file(filename.c_str(), std::ios::binary | std::ios::trunc);
    std::copy(
          buffer.begin()
        , buffer.end()
        , std::ostream_iterator<char>(file)
    );
}

Автор: php5 14.8.2013, 09:36
Спасибо SenkraD !

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)