c++ функции Чтение байтов один за другим из двоичного файла



функции для работы с бинарными файлами с++ (1)

это мой вопрос, я хочу открыть файл .jpg и записать каждый байт в виде десятичного числа (0-255), разделенного запятой, в другой .txt-файл. теперь он должен иметь возможность снова создавать файл .jpf, используя этот файл txt. вот как я пытался это сделать.

#include<iostream>
#include<fstream>
using namespace std;
int main()
{
long x;
char *s;

ifstream ifs("image.jpg",ios::binary);
ifs.seekg(0,ios::end);
x=ifs.tellg();
ifs.seekg(0,ios::beg);

s=new char[x];
ifs.read(s,x);
ifs.close();

ofstream is("image.txt");

for(int i=0;i<x;i++){
is<<(unsigned int)s[i]<<",";
}

теперь эта программа создает image.txt с десятичными числами следующим образом: 4294967295,4294967256,4294967295,4294967264,0,16,74,70,73,70,0,1, ...... здесь некоторые цифры, кажется, 4 байт long, s [i] ссылается только на один байт, так как может (int) s [i] вернуть большое число, чем 255. пожалуйста, может кто-то помочь мне в этом .... спасибо ..


Кажется, на вашем компьютере подписан char . Поэтому, когда вы отбрасываете отрицательное число в unsigned int , вы получаете большое значение. Большие значения на выходе представляют собой отрицательные значения при их представлении с использованием char . Обратите внимание, что когда char подписан , его значение может быть от -128 до 127 но байт может быть от 0 до 255 . Поэтому любое значение, большее 127 , станет отрицательным в диапазоне от -128 to -1 .

Используйте unsigned char как:

unsigned char *s;

Или сделайте это:

is<< static_cast<unsigned int> (static_cast<unsigned char>(s[i]) )<<",";
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                casting to unsigned char first
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
               then casting to unsigned int 

То есть, отбрасывает первый char в unsigned char , а затем в unsigned int .

Ну, это все о проблеме, с которой вы сталкиваетесь. Теперь некоторые заметки о стиле и идиомах. В C ++ вы должны избегать использования как можно большего числа new . В вашем случае вы можете использовать std::vector как:

//define file stream object, and open the file
std::ifstream file("image.jpg",ios::binary);

//prepare iterator pairs to iterate the file content!
std::istream_iterator<unsigned char> begin(file), end;

//reading the file content using the iterator!
std::vector<unsigned char> buffer(begin,end);

Последняя строка считывает все данные из файла в buffer . Теперь вы можете напечатать их как:

std::copy(buffer.begin(), 
          buffer.end(), 
          std::ostream_iterator<unsigned int>(std::cout, ","));

Чтобы все это работало, вам необходимо включить следующие заголовки в дополнение к тому, что вы уже добавили в свой код:

#include <vector>     //for vector
#include <iterator>   //for std::istream_iterator and std::ostream_iterator
#include <algorithm>  //for std::copy

Как вы можете видеть, это идиоматическое решение не использует указатель и new , и не использует ли он!





byte