C++二进制文件读入结构体

发布于 2024-12-19 00:44:52 字数 642 浏览 2 评论 0原文

我使用如下结构编写了一个二进制文件:

struct block{
char data[32];
};

所以我最终得到的基本上是一个充满 char[32] 的大型二进制文件。数据被格式化在特定的位置,因此获取特定的信息并不困难。但是,我尝试像这样读取文件:

int lines=0;
std::ifstream inputFile("file.bin",std::ios::binary);

while (!inputFile.eof())
{
    inputFile.read(blocks[lines].data, sizeof(block));
    lines++;
}

inputFile.close();
lines--;

然后像这样显示它:

std::cout<<"block 1: "<<blocks[0].data<<std::endl;
// etc ...

我认为blocks[i].data应该只给我属于索引i的char[32],但它却给了我每个“数据” " 结构中从该索引到结构末尾的元素。我确信这是我对其工作原理的误解。我的问题是:如何获取blocks[i].data 表示的char[32]?

I have written a binary file using a struct as follows:

struct block{
char data[32];
};

so what I end up with is basically a large binary file full of char[32]. The data is formatted in specific positions so grabbing specific pieces of information is not difficult. However, I tried to read the file like so:

int lines=0;
std::ifstream inputFile("file.bin",std::ios::binary);

while (!inputFile.eof())
{
    inputFile.read(blocks[lines].data, sizeof(block));
    lines++;
}

inputFile.close();
lines--;

and then displaying it like this:

std::cout<<"block 1: "<<blocks[0].data<<std::endl;
// etc ...

I thought that blocks[i].data should just give me the char[32] that belongs to index i, but it instead gives me every "data" element in the struct from that index to the end of the struct. I'm sure that it is my misunderstanding of how that works. My question is: how do I just get the char[32] represented by blocks[i].data?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

她比我温柔 2024-12-26 00:44:52

问题在于您的 std::cout 输出语句。当您尝试输出 blocks[0].data 时,operator<< 得到的不是 32 个字符的数组,而是一个指针到第一个字符。这被解释为指向 C 字符串的指针,因此它会输出从那里开始在内存中找到的所有字符,直到找到 '\0'。由于每个数组元素仅包含文件中相应的字符,因此文件中的所有字符都会被输出(除非文件中存在 '\0',则输出将在那里停止)。另外,您似乎(不)幸运的是 '\0' 跟随内存中的数据,因此输出在那里停止(而不是继续输出内存中的任何内容,并且可能给出当到达进程内存末尾时出现分段错误)。

要仅将 32 个字符输出为字符,请使用 std::cout.write(blocks[0].data,32)。否则,要将它们输出为整数,只需循环遍历它们并将每个转换为整数:

for (int i = 0; i < 32; ++i)
  std::cout << static_cast<int>(blocks[0].data[i]) << ' ';

当然,您可以使用所有流操纵器来获取所需形式的数字(例如, std::hex 表示十六进制输出,和/或 std::setwstd::setfill 以获得固定宽度的数字)。

The problem is your std::cout output statement. When you try to output blocks[0].data, what operator<< gets is not the array of 32 chars, but a pointer to the first char. This is interpreted as pointer to a C string, and therefore it outputs all characters found in memory from there on until it finds a '\0'. Since each array element contains just the corresponding characters from the file, all characters of the file are output (unless there's a '\0' in the file, then output stops there). Also, you seem to be (un-)lucky that a '\0' follows your data in memory, so the output stops there (instead of continuing to output whatever is in memory afterwards, and possibly giving a segmentation fault when the end of the process' memory is reached).

To just output the 32 charactes as characters, use std::cout.write(blocks[0].data,32). Otherwise to output them as ints just loop through them and convert each one to int:

for (int i = 0; i < 32; ++i)
  std::cout << static_cast<int>(blocks[0].data[i]) << ' ';

Of course you can use all the stream manipulators to get the numbers in the form you want (e.g. std::hex for hexadecimal output, and/or std::setw and std::setfill to get fixed width numbers).

梦幻的味道 2024-12-26 00:44:52
std::cout<<"block 1: "<<blocks[0].data<<std::endl;

您将 char[] 发送到流,该流被提升为 char*,因此它认为它是一个以 NULL 结尾的字符串,并尝试将其显示为这样。很难说出你想要什么,但这会以十六进制显示它:

std::cout << std::setfill('0') << std::hex;
for(int i=0; i<25; ++i)
    std::cout << std::setw(2) << blocks[0].data[i];
std::cout << std::setfill(' ') << std::dec;
std::cout<<"block 1: "<<blocks[0].data<<std::endl;

You're sending a char[] to the stream, which gets promoted to a char*, so it thinks it's a NULL terminated string, and attempts to display it as such. It's hard to tell what it is that you want, but this will display it in hexidecimal:

std::cout << std::setfill('0') << std::hex;
for(int i=0; i<25; ++i)
    std::cout << std::setw(2) << blocks[0].data[i];
std::cout << std::setfill(' ') << std::dec;
我为君王 2024-12-26 00:44:52

您的输入部分需要更改:

while (inputFile.read(blocks[lines].data, sizeof(block))
{
     lines++;
}

原因是直到读取操作发生之后之后才确定 EOF 条件。使用 EOF 检查的一个副作用是可能会读取额外的行。

Your input section needs to be changed:

while (inputFile.read(blocks[lines].data, sizeof(block))
{
     lines++;
}

The reason is that the EOF condition is not determined until AFTER a read operation occurs. One side effect of your use of EOF checking is that an extra line may be read.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文