我有这个struct
与2个属性(一个char和一个int,内存使用量为3字节:
struct Node {
char data;
int frequency;
}
我尝试重载操作符<<和比;比;对于这个struct
,因为能够使用fstream
从文件中读写这个struct
。对于运算符<<我:
friend std::ostream& operator<<(std::ostream& output, const HuffmanNode& e) {
string data = string(1, e.data) + to_string(e.frequency);
output << data.data();
return output;
};
这让人想知道这将返回多少空间到输出(3字节,如预期的那样?- 1来自char类型,2来自int类型?)
当我想保存struct
的文件,我得到这个:
List<Node> inOrder = toEncode.inOrder();
for(int i=1; i<=inOrder.size(); i++) {
output << inOrder.get(i)->getData();
其中列表的每个节点inOrder和树toEncode上面是前面列出的struct
,iNOrder.get(i)->getData()
返回它。output
是fstream
。
现在,我如何从文件中读取?使用操作符>>,我所理解的是,它需要一个具有3个元素的unsigned char
数组作为输入,并将第一个元素(1字节)转换为char,以及其他2个元素并转换为int。这是正确的吗?我可以用这个方法来做吗:
friend std::istream& operator>>(std::istream& input, HuffmanNode& e) {
...
};
或者我需要更改方法签名(和参数)?对于文件读取本身,考虑到我需要读取的字符都在文件的第一行,什么代码使程序每次从这行读取3个字符并从该数据生成struct
?
我得到了什么:
写入文件,我实现了这个操作符<<:
friend std::ostream& operator<<(std::ostream& output, const HuffmanNode& e) {
union unsigned_data data;
data.c = e.data;
union unsigned_frequency frequency;
frequency.f = e.frequency;
output << data.byte << frequency.byte;
return output;
};
的用法:
List<HuffmanNode> inOrder = toEncode.inOrder();
for(int i=1; i<=inOrder.size(); i++)
output << inOrder.get(i)->getData();
这似乎工作,但我不能确定没有办法从文件中读取,我得到了这个:
operator>祝辞:
friend std::istream& operator>>(std::istream& input, HuffmanNode& e) {
union unsigned_data data;
data.c = e.data;
union unsigned_frequency frequency;
frequency.f = e.frequency;
input >> data.byte >> frequency.byte;
return input;
};
的用法:
string line;
getline(input, line);
HuffmanNode node;
stringstream ss(line);
long pos = ss.tellp();
do {
ss >> node;
toDecode.insert(node);
ss.seekp (pos+3);
} while(!ss.eof());
似乎陷入了无限循环。两个操作符都使用了这个联合:
union unsigned_data {
char c;
unsigned char byte;
};
union unsigned_frequency {
int f;
unsigned char byte[sizeof(int)];
};
这将返回多少空间到输出(如预期的3字节)?- 1来自char类型,2来自int类型?)
。您正在将值转换为std::string
s,因此它们具有变量长度,具体取决于特定值(即,"123"
占用与"1234567890"
不同的长度)。您所描述的适用于值的二进制存储,而不适用于值的文本表示。
现在,我如何从文件中读取?使用操作符>>,我所理解的是,它需要一个具有3个元素的
unsigned char
数组作为输入,并将第一个元素(1字节)转换为char,以及其他2个元素并转换为int。这是正确的吗?
。operator<<
和operator>>
主要用于格式化的(文本)的I/O。您的operator<<
实际上正在编写格式化的输出(不过,您不需要首先将值转换为std::string
s,您可以使用operator<<
的相关重载按原样编写它们)。您只需要以operator>>
可以反转的方式编写格式化的数据。例如:
friend std::ostream& operator<<(std::ostream& output, const HuffmanNode& e) {
output << int(e.data) << ' ' << e.frequency << ' ';
return output;
}
friend std::istream& operator>>(std::istream& input, HuffmanNode& e) {
int i;
input >> i >> e.frequency;
e.data = char(i);
input.ignore();
return input;
}
另外:
friend std::ostream& operator<<(std::ostream& output, const HuffmanNode& e) {
output << e.data << e.frequency << 'n';
return output;
}
friend std::istream& operator>>(std::istream& input, HuffmanNode& e) {
e.data = input.get();
input >> e.frequency;
input.ignore();
return input;
}
格式完全取决于你,根据你的特殊需要。
然而,操作符也可以用于读写二进制数据(只是要确保以binary
模式打开流),例如:
friend std::ostream& operator<<(std::ostream& output, const HuffmanNode& e) {
output.write(&e.data, sizeof(e.data));
output.write(reinterpret_cast<const char*>(&e.frequency), sizeof(e.frequency));
return output;
}
friend std::istream& operator>>(std::istream& input, HuffmanNode& e) {
input.read(&e.data, sizeof(e.data));
input.read(reinterpret_cast<char*>(&e.frequency), sizeof(e.frequency));
return input;
}
这更符合你的想法。