Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 理解二进制转换_C++_Binary_Binaryfiles - Fatal编程技术网

C++ 理解二进制转换

C++ 理解二进制转换,c++,binary,binaryfiles,C++,Binary,Binaryfiles,我正在编写一个资源文件,我想从各种常见文件(例如.JPG、.BMP)中插入一组数据,我希望它是二进制的。 我将编写一些代码,以便稍后按索引组织检索这些数据,到目前为止,我得到的是: float randomValue = 23.14f; ofstream fileWriter; fileWriter.open("myFile.dat", ios::binary); fileWriter.write((char*)&randomValue, sizeof(randomValue)); f

我正在编写一个资源文件,我想从各种常见文件(例如.JPG、.BMP)中插入一组数据,我希望它是二进制的。 我将编写一些代码,以便稍后按索引组织检索这些数据,到目前为止,我得到的是:

float randomValue = 23.14f;

ofstream fileWriter;
fileWriter.open("myFile.dat", ios::binary);
fileWriter.write((char*)&randomValue, sizeof(randomValue));
fileWriter.close();
//With this my .dat file, when opened in notepad has "B!¹A" in it

float retrieveValue = 0.0f;

ifstream fileReader;
fileReader.open("myFile.dat", ios::binary);
fileReader.read((char*)&retrieveValue, sizeof(retrieveValue));
fileReader.close();

cout << retrieveValue << endl; //This gives me exactly the 23.14 I wanted, perfect!
据我所知,这将只在文件中写入第一个地址值,而不是所有数组。因此,为了进行测试,我试图简单地将一个变量转换为一个char*,然后将其写入一个文件,然后转换回该变量,以查看我是否正确地检索了值,因此我同意以下观点:

int* intArray = new int[10];
for(int i = 0; i < 10; i++)
{
    cout << &intArray[i]; //the address of each number in my array
    cout << intArray[i]; //it's value
    cout << reinterpret_cast<char*>(&intArray[i]); //the char* value of each one     
}
然后在读取资源文件的代码中,我想做如下操作(未测试):

目前,我的代码正在处理原始文件(BMP、WAV等)并将它们填充到类中,我想知道如何将这些文件中的数据保存到二进制数据文件中。 例如,管理BMP数据的我的类有:

class FileBMP
{
    public:
        int imageWidth;
        int imageHeight;
        int* imageData;
}
当我加载它时,我调用:

void FileBMP::Load(int iwidth, int iheight)
{
    int imageTotalSize = iwidth * iheight * 4;
    imageData = new int[imageTotalSize]; //This will give me 4 times the amount of pixels in the image

    int cPixel = 0;
    while(cPixel < imageTotalSize)
    {
        imageData[cPixel] = 0;     //R value
        imageData[cPixel + 1] = 0; //G value
        imageData[cPixel + 2] = 0; //B value
        imageData[cPixel + 3] = 0; //A value
        cPixel += 4;
    }
} 
void FileBMP::Load(intiwidth,intiheight)
{
int imageTotalSize=iwidth*iheight*4;
imageData=new int[imageTotalSize];//这将使图像中的像素数量增加4倍
int-cPixel=0;
while(cPixel
因此,我有一个一维数组,包含每像素[RGBA]格式的值,稍后我将使用它在屏幕上绘制。 我希望能够以我计划的二进制数据格式(如上所述)保存这个数组,然后读取它并填充这个数组

我认为这样的代码要求太高了,所以我想了解我需要知道什么才能将这些值保存到二进制文件中,然后读回以填充它

抱歉发了这么长的帖子


edit2:我通过第一次编辑解决了我的问题。。。谢谢你的宝贵信息,我也知道我想要什么

发生的事情是,您正在复制内部 将数据表示为文件,然后将其复制回 在内存中,只要程序执行 编写是用同一版本的编译器编译的, 使用相同的选项。否则,它可能会,也可能不会 工作,取决于你无法控制的任何事情

我不清楚你想做什么,但是 .jpg和.bmp通常指定所需的格式
要有不同的类型,你必须尊重这种格式。

不清楚你真正想做什么,所以我不能推荐一种解决你真正问题的方法。但是,如果运行该程序确实导致程序中出现哔哔声或任何其他奇怪的行为,我不会感到惊讶

int* intArray = new int[10];
for(int i = 0; i < 10; i++)
{
    cout << reinterpret_cast<char*>(&intArray[i]);
}
int*intArray=newint[10];
对于(int i=0;i<10;i++)
{

cout通过使用&运算符,您将获得一个指向变量内容的指针(将其视为一个内存地址)

当您为write()指定(char*)&randomValue时,您只是告诉“获取具有char数据的内存地址,然后从那里写入(randomValue)chars的大小”。您不是在写入地址值本身,而是来自内存位置的内容(“原始二进制数据”)

如果要编写结构,请查看#pragma pack compiler指令。编译器将把(使用padding)变量对齐到特定大小(int),这意味着以下结构实际上可能需要8个字节:

#pragma pack (push, 1)
struct CouldBeLongerThanYouThink
{
  char a;
  char b;
};
#pragma pack (pop)

另外,不要写入指针值本身(如果结构中有指针成员),因为一旦从文件中读回,内存地址将不会指向任何有意义的数据。始终写入数据本身,而不是指针值。

哦,这就是为什么我会收到无效访问内存错误的原因…但是,第一块代码,它对未指定的字节没有任何问题吗?float是4个字节,char是1个字节,会发生什么情况其他3个字节,当我说将其视为字符*?(我不想在转换和保存到文件时丢失信息)当您告诉write()写入4个字符时,无论指针指向何处或数据的实际类型,它都会尝试这样做。read()也是如此C++并不真正关心你到底有多少字节或者你有什么类型,Char *只是告诉你指针应该指向一个字符。你也不应该相信这个字符是单字节,即使几乎总是。一些读写函数以空洞*输入和字节数作为参数。(与需要字符的fstream方法不同)。
class FileBMP
{
    public:
        int imageWidth;
        int imageHeight;
        int* imageData;
}
void FileBMP::Load(int iwidth, int iheight)
{
    int imageTotalSize = iwidth * iheight * 4;
    imageData = new int[imageTotalSize]; //This will give me 4 times the amount of pixels in the image

    int cPixel = 0;
    while(cPixel < imageTotalSize)
    {
        imageData[cPixel] = 0;     //R value
        imageData[cPixel + 1] = 0; //G value
        imageData[cPixel + 2] = 0; //B value
        imageData[cPixel + 3] = 0; //A value
        cPixel += 4;
    }
} 
int* intArray = new int[10];
for(int i = 0; i < 10; i++)
{
    cout << reinterpret_cast<char*>(&intArray[i]);
}
float a = 123.45f;
float* p = &a; // now p points to a, i.e. has the memory address to a's contents.
char* c = (char*)&a; // c points to the same memory location, but the code says to treat the contents as char instead of float.
cout << reinterpret_cast<char*>(&intArray[i]); //the char* value of each one 
float randomValue = 23.14f;
char* charValue = reinterpret_cast<char*>(&randomValue);

float back = *(float*)charValue;
    int values[3] = { 5, 6, 7 };
struct AnyData
{
   float a;
   int b;
} data;

cout.write((char*)&values, sizeof(int) * 3); // the other two values follow the first one, you can write them all at once.
cout.write((char*)&data, sizeof(data)); // you can also save structs that do not have pointers.
#pragma pack (push, 1)
struct CouldBeLongerThanYouThink
{
  char a;
  char b;
};
#pragma pack (pop)