【问题标题】:Overloading istream operator重载 istream 运算符
【发布时间】:2021-12-16 13:26:57
【问题描述】:

我有一个字符串类。我想重载运算符>>。找到了以下方式,但据我了解,最后没有添加零字符(行终止符)。怎样才能写出好的算子>>?

class String {
 public:
  char* str;
  size_t size;
  size_t capacity;

  ~String();
  String(const char*);
  friend std::istream& operator>>(std::istream&, String&);
};

std::istream& operator>>(std::istream& is, String& obj) {
      is.read(obj.str, obj.size);
      return is;
    }

【问题讨论】:

  • 你可以用obj.str[obj.size] = '\0'; 终止你的字符串...但是你有一个更基本的问题,那就是你的设计要求你分配一个长度完全正确的字符串before 从流中读取它。这不是来自流的字符串输入的工作方式。
  • @paddy 也就是需要在类外写一个单独的函数来实现?我不明白如何为我行事。我也做了 obj.str [obj.size] = '\ 0' 但我从 Valgrind 得到错误。分段错误(核心转储)
  • 如果您尝试模拟标准字符串输入,则需要一次读取一个字符,直到确定字符串完整为止。也就是说,当您遇到任何空白字符时。每次读取一个字符时,都需要将其附加到字符串中,这意味着如果容量不足,您还需要增加字符串缓冲区。完成后,您编写一个最终的字符串终止符(如果您的课程需要它)。

标签: c++ string istream


【解决方案1】:

让我们从显而易见的部分开始:您的operator>> 需要根据您读取的输入实际创建一个有效的String 对象。假设您要读取整行输入作为字符串(在换行处停止,或某个最大字符数)。

目前,我将假设任何Stringstr 成员要么是空指针,要么是指向使用new 分配的数据的指针。

std::istream &operator>>(std::istream &is, String &obj) { 
    static char buffer[max_size];

    is.getline(buffer, max_size);
    std::size_t size = std::strlen(buffer);
    if (size > 0) {
        if (size > obj.size) {
            delete [] obj.str;
            obj.str = new char [size+1];
            obj.capacity = size;
        }
        strcpy(obj.str, buffer);
        obj.size = size;
    }
    return is;
}

这并不是为了处理所有极端情况(例如,它没有错误处理),但至少给出了大致的想法——你需要阅读文本,检查你是否有足够的空间存储文本,根据需要分配更多,将文本复制到(现有或新分配的)空间中,并至少将大小更新为当前大小,如果重新分配,容量也会更新为更新后的容量。

【讨论】:

  • 从文件中读取缓冲区后,它应该只使用现有的const char* 构造函数。
猜你喜欢
  • 2013-10-10
  • 2011-09-23
  • 2020-02-10
  • 1970-01-01
  • 2021-08-07
  • 1970-01-01
  • 2017-05-26
  • 2011-08-31
  • 2011-03-19
相关资源
最近更新 更多