MST

星途 面试题库

面试题:C++ string类I/O自定义扩展

假设你需要为C++ string类扩展一种新的I/O格式,例如一种特殊的二进制编码格式用于高效存储和传输string数据。请设计实现一个新的输入输出操作符(`<<`和`>>`)重载,使得可以将string对象以这种自定义的二进制格式写入输出流,并从输入流中正确读取并还原为string对象。阐述设计思路、实现步骤以及可能遇到的问题及解决方案。
13.8万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 自定义二进制格式设计:确定如何将字符串数据编码为二进制格式。例如,可以在二进制数据开头存储字符串的长度,然后紧接着存储字符串的字符内容。
  2. 输出操作符 << 重载:将字符串按照自定义二进制格式写入输出流。
  3. 输入操作符 >> 重载:从输入流中按照自定义二进制格式读取数据,并还原为字符串对象。

实现步骤

  1. 输出操作符 << 重载
#include <iostream>
#include <string>

std::ostream& operator<<(std::ostream& os, const std::string& str) {
    // 先写入字符串长度
    size_t length = str.size();
    os.write(reinterpret_cast<const char*>(&length), sizeof(length));
    // 再写入字符串内容
    os.write(str.c_str(), length);
    return os;
}
  1. 输入操作符 >> 重载
std::istream& operator>>(std::istream& is, std::string& str) {
    size_t length;
    // 先读取字符串长度
    is.read(reinterpret_cast<char*>(&length), sizeof(length));
    if (!is) {
        return is;
    }
    // 读取字符串内容
    str.resize(length);
    is.read(&str[0], length);
    return is;
}
  1. 测试代码
int main() {
    std::string test = "Hello, World!";
    std::stringstream ss;
    // 将字符串写入流
    ss << test;

    std::string result;
    // 从流中读取字符串
    ss >> result;

    std::cout << "Original: " << test << std::endl;
    std::cout << "Read back: " << result << std::endl;

    return 0;
}

可能遇到的问题及解决方案

  1. 字节序问题:不同系统的字节序可能不同。解决方案是在写入和读取长度等数值时,可以使用网络字节序相关函数(如 htonlntohl 等)进行转换,确保在不同系统间的兼容性。
  2. 流错误处理:在读取操作符 >> 中,如果读取长度或内容失败,流会进入错误状态。通过检查 is 的状态并返回 is,调用者可以检查流是否处于有效状态,以决定后续操作。
  3. 数据完整性:如果在写入或读取过程中发生中断,数据可能不完整。可以在自定义格式中加入校验和(如CRC)来验证数据的完整性。在写入时计算校验和并写入,读取时重新计算并与读取的校验和比较。