Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.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++;文件IO:读写16位字_C++_Stl_Iostream_Widechar - Fatal编程技术网

C++ C++;文件IO:读写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

我想把非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.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) );