C++ C++;文件IO:读写16位字
我想把非Unicode的16位字写入一个文件,然后再读回。我知道,通过一点字节操作,我可以在C++ C++;文件IO:读写16位字,c++,stl,iostream,widechar,C++,Stl,Iostream,Widechar,我想把非Unicode的16位字写入一个文件,然后再读回。我知道,通过一点字节操作,我可以在char模式下使用fstream::read()和fstream::write()。直接使用16位单词需要做什么 例如,我似乎应该能够做到以下几点: basic_ofstream<uint16_t> aw; aw.open("test.bin", ios::binary); uint16_t c[] = {0x55aa, 0x1188}; aw.write(c, 2); aw.clo
char
模式下使用fstream::read()
和fstream::write()
。直接使用16位单词需要做什么
例如,我似乎应该能够做到以下几点:
basic_ofstream<uint16_t> aw;
aw.open("test.bin", ios::binary);
uint16_t c[] = {0x55aa, 0x1188};
aw.write(c, 2);
aw.close();
basic_ifstream<uint16_t> ax;
ax.open("test.bin", ios::binary);
uint16_t ui[2];
ax.read(ui, 2);
ax.close();
cout << endl << hex << unsigned(ui[0]) << " " << unsigned(ui[1]) << endl;
Vc++10输出:
CCCC CCCC
我还尝试过直接使用std::basic_filebuf
direct,得到了相同的结果。为什么?我建议阅读:
片段:
“这些类型的问题是它们的大小没有得到很好的定义。
int在一台机器上可能是8个字节,但在另一台机器上只有4个字节
唯一一致的是char…它保证总是一致的
1字节。“
u16 ReadU16(istream和文件)
{
u16-val;
u8字节[2];
read((char*)字节,2);//从文件中读取2个字节
val=bytes[0]|(bytes[1]>8)&0xFF;//高位字节
//将这些字节写入文件
写入((char*)字节,2);
}
您可能还需要刷新“typedef”关键字,以定义保证的-#位类型。Boost和C99编译器虽然只是一个学习曲线,但它们也定义了保证大小的类型。我不确定X++0x,但它太新了,无法移植。我真的很惊讶您将流实例化来进行任何读取!结果可能是实现定义的(即,您可能会发现编译器文档中描述的行为),但可能只是没有指定(尽管没有完全定义)。我认为流类不需要立即支持除
char
和wchar\u t
之外的其他类型的实例化,也就是说,用户不提供至少一些方面
标准流类是字符类型上的模板,但对于任何不支持的类型都不容易实例化。至少,您需要实现一个合适的std::codevt
facet,在字节的外部表示和内部表示之间进行转换。从外观上看,您尝试的两个系统对其默认实现做出了不同的选择
std::codevt
是用于在字符的外部表示和内部表示之间转换的方面。流只需要支持char
,它被认为是将字节表示为外部类型externT
。内部字符类型internT
可以是任何整数类型,但需要通过实现代码转换方面来定义转换。如果我没有记错的话,流还可以假设状态类型stateT
是std::mbstate\t
(这实际上有点问题,因为没有为此类型定义接口!)
除非您真正致力于为您的字符类型创建I/O流,否则您可能希望使用
std::ifstream
读取字节并将其转换为您的字符类型。同样地,书写字符也是如此。要真正创建一个也支持格式化的I/O流,您还需要许多其他方面(例如,std::ctype
,std::num_punct
),并且您需要构建一个std::locale
来包含所有这些方面以及一些可以从标准库实现中实例化的方面(例如,std::num_get
和std::num_put
;我认为它们的迭代器类型是合适的默认值)。当我尝试你的代码时,文件被写入,但里面什么都没有,关闭后它的大小是0。从该文件读取时,什么都无法读取。你在输出中看到的是未初始化的垃圾
除了使用带有默认字符的ofstream/ifstream外,您不必依赖于read()
和write()
方法,因为它们不指示它们是否实际写入了任何内容。有关此方面的详细信息,请参阅。特别有趣的是:
此函数是一个未格式化的输出函数:它从
构造sentry类型的对象,该对象刷新tie()
如有必要,输出缓冲区并检查流错误
构造时,如果sentry对象返回false,则函数返回
不尝试任何输出
这可能就是为什么没有将输出写入文件的原因,因为它似乎不适用于除char或类似类型之外的任何其他类型
更新:要查看写入/读取是否成功,请检查失败或错误位,该位应已指示出现了错误
cout << aw.fail() << aw.bad() << "\n";
cout << ax.fail() << ax.bad() << "\n";
cout您可以使用字符专门化和重新解释\u cast:
basic_ofstream<char> aw;
...
aw.write( reinterpret_cast<const char*>(i16buf), n2write*sizeof(int16_t) );
basic_ifstream<char> ax;
...
ax.read( reinterpret_cast<char*>(i16buf), n2read*sizeof(int16_t) );
流式电弧焊的基本原理;
...
aw.write(重新解释强制转换(i16buf),n2write*sizeof(int16_t));
基本流ifax;
...
ax.read(重新解释铸件(i16buf),n2read*sizeof(int16_t));
“sizeof(int16_t)”用于sizeof(int16_t)==1的边缘情况(例如DSP处理器)
当然,如果您需要以特定的字节顺序读/写,那么您就需要endian转换函数。请注意,没有标准的编译时方法来确定endian。首先,您需要读取和写入不同的数量。我不认为这就是为什么您会看到Cs,但您必须修复它sometime@Wug,这是一个削减和过去e错误。将修复。“类模板basic_filebuf
将文件视为字节的源或汇”-§27.9.1[fstreams]/3FWIW,char可以是一个字节,但这并不意味着8位。例如,TI定点DSP具有16位char sizeof(int)=sizeof(short)=sizeof(char 1)aw.write(reinterpret_cast(c),sizeof c);/?这是真的,而且完全不重要,直到一些程序员忘记并假设他的平台的字节是每个人的。阅读此问题的读者可能会注意到limit.h(C++中的climit)定义了CHAR\u bit
中每位的#字节数。
cout << aw.fail() << aw.bad() << "\n";
cout << ax.fail() << ax.bad() << "\n";
basic_ofstream<char> aw;
...
aw.write( reinterpret_cast<const char*>(i16buf), n2write*sizeof(int16_t) );
basic_ifstream<char> ax;
...
ax.read( reinterpret_cast<char*>(i16buf), n2read*sizeof(int16_t) );