我正在尝试创建压缩程序,但我需要了解如何以二进制文件打开文件并打印出其内容的基础知识。
在一个名为“Tester.txt”的文本文件中,我有:
MJ
在.cpp文件中,我有这个:
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main
{
fstream istr;
istr.open("Tester.txt", ios::binary);
}
根据我在cplusplus参考中的理解,这使用一个流对象来打开二进制文件中指定的文件?
但我仍然坚持如何“打印”文件的第一个字节,即二进制字母M?
我知道二进制的M(大写字母)是01001101。
那么如何在二进制文件中做一个M的cout?
由于
答案 0 :(得分:3)
数字和数字表示之间存在混淆,可能是由于“二进制”这个词有时可用于描述两者而产生的。以“二进制模式”打开文件时,这意味着您将看到文件中字节的原始值。在表示基数为2的数字意义上,这与“二进制”有 nothing 。
假设某个文件有“x”后跟换行符和返回值。在“二进制模式”中,您将看到三个字节大小的值,一个包含“x”的ASCII代码,一个包含换行的ASCII代码,另一个包含返回的ASCII代码。这些是您从文件中读取的值。 可以以二进制形式表示它们,但您也可以用十进制或十六进制表示它们,您仍然可以从文件中读取完全相同的值。
以“二进制”方式读取文件会确定您阅读的值,而不是您如何表示它们。两辆车是相同的两辆车,无论你是代表值两个是“2”(十进制),“10”(二进制)还是“两个”(英语)。
答案 1 :(得分:2)
流上的二进制输入/输出使用其成员函数read()
和write()
完成。
像这样:
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main
{
fstream istr;
istr.open("Tester.txt", ios::binary);
if (istr) {
// Read one byte
char byte;
if (!istr.read(&byte, 1)) {
// Error when reading
}
// Alternative way to read one byte (thanks to DyP)
byte = istr.get();
// Another alternative:
if (!istr.get(byte)) {
// Error when reading.
}
// Read a block of bytes:
char buffer[1024];
if (!istr.read(buffer, 1024)) {
// Read error, or EOF reached before 1024 bytes were read.
}
}
}
答案 2 :(得分:1)
要输出二进制值,您需要手动执行,因为标准库不支持该输出格式。
int mask = 0x80;
while(mask)
{
std::cout << (byteValue & mask ? '1' : '0');
mask >>= 1;
}
std::cout << std::endl;
这将从顶部位扫描到低位并打印出代表每个位的值。
答案 3 :(得分:1)
这是一个快速程序,它使用C ++标准库来完成所有繁重的工作。
#include <iostream>
#include <iterator>
#include <bitset>
#include <algorithm>
int main() {
std::istreambuf_iterator< char > in( std::cin ), in_end;
std::ostream_iterator< std::bitset< 8 > > out( std::cout, " " );
std::copy( in, in_end, out );
std::cout << '\n';
}
See it run.我使用std::cin
进行演示,但您应该打开一个std::ios::binary
的文件,然后传递它。
由于每个变量仅使用一次,因此可以在一行上完成。即使您打开文件而不是使用std::cin
。
修改强>
std::copy
是封装循环for ( ; in != in_end; ++ in ) * out ++ = * in;
。std::istreambuf_iterator
要么使用istream
构造函数参数并提供适合此类循环的迭代器in
,要么不接受构造函数参数并提供迭代器in_end
等in == in_end
如果in.eof() == true
。迭代器从流中获取未格式化的字节(类型char
)。std::ostream_iterator< std::bitset< 8 > >
提供了一个迭代器out
,因此* out ++ = x
会将x
转换为std::bitset< 8 >
并打印结果。在这种情况下,x
是一个字节,bitset
为这样的字节值提供构造函数,并重载operator<<
以打印1和0的二进制表示。答案 4 :(得分:0)
试试这个:
#include <fstream>
#include <iostream>
#include <string>
#include <bitset>
#include <iomanip>
int main()
{
// Set up your objects.
char c;
std::fstream istr("Tester.txt", ios::binary);
unsigned long loc = 0;
// Read the file one character at a time.
// Remembering not to skip white space in this situation.
for(;istr >> std::noskipws >> c;++loc)
{
// When printing compensate for non printable characters.
// If the character is outside the ASCII range then print it as an integer.
std::stringstream charStr;
if ((c < 32) || (c > 126))
{
charStr << "Char: " << c;
}
else
{
charStr << "Non Printable: " << static_cast<int>(c);
}
// Print the value and location in a nicely formatted way.
std::cout << std::setw(16) << location
<< " : "
<< std::bitset<8>(c).to_string() // Prints the character as an 8 bit binary value.
<< " : "
<< charStr.str()
<< "\n";
}
}
但是有一些标准工具可以做到这一点: