【问题标题】:Using strchr to overload >>使用 strchr 重载 >>
【发布时间】:2016-07-05 19:35:06
【问题描述】:

我正在尝试重载 >> 运算符以读取单个(使用 enum Symbol {e,a,b,c,d}; 创建)符号:

istream & operator >> (istream & is, Symbol & sym) {
  Symbol Arr[]={e,a,b,c,d};
  char ch;
  is>>ch;
  if (strchr("eabcd",ch))
    sym=Arr[ch-'e'];
      else {
        is.unget(); 
        is.setstate(ios::failbit);
      }
  return is;
}

但这读取了一些垃圾(数字)而不是我正在寻找的内容,导致尝试使用我的 using namespace std;,同样包括iostreamcstring

【问题讨论】:

  • 只是好奇,你想解决什么问题?
  • 这是我在大学的对象编程课程的一个较大项目的一部分,我需要阅读符号,然后使用加法表等对它们进行操作。

标签: c++ operator-overloading inputstream strchr


【解决方案1】:

如果ch'a'ch - 'e' (97 - 101) 将是一个负数 (-4),这将导致访问数组 Arr 越界。这会导致未定义的行为。

您拥有符号的方式,您需要使用switch 声明:

switch (ch)
{
   case 'a':
      sym = a;
      break;

   case 'b':
      sym = b;
      break;

   case 'c':
      sym = c;
      break;

   case 'd':
      sym = d;
      break;

   case 'e':
      sym = e;
      break;

   default:
     // Nothing to do
     break;
}

如果你想使用Arr,你需要将Arr定义为:

 Symbol Arr[]={a,b,c,d,e};

然后,您可以按如下方式访问数组并避免switch 语句:

sym=Arr[ch-'a'];  // ch - 'a' is 0 when ch is 'a'
                  // ch - 'a' is 4 when ch is 'e'.

【讨论】:

  • 'e' - ch 将不起作用,因为Arr 的元素不是按从ea 的顺序排列的。
  • @RemyLebeau,感谢您指出错误。现在已经修好了。
【解决方案2】:

这里有一些问题。首先,让我们修复你的支撑。只是总是使用大括号。很难看出什么与什么对齐:

istream & operator >> (istream & is, Symbol & sym) {
    Symbol Arr[]={e,a,b,c,d};
    char ch;
    is>>ch;
    if (strchr("eabcd",ch)) {
        sym=Arr[ch-'e'];
    }
    else {
        is.unget(); 
        is.setstate(ios::failbit);
    }
    return is;
}

好的很好。现在,如果用户输入类似'a' 的内容会发生什么。 strchr 成功,然后您执行 sym = Arr[ch - 'e']。但是在这种情况下ch - 'e'-4。那是某处完全随机的内存,所以你得到了垃圾。要实际使用strchr,您需要执行以下操作:

const char* options = "eabcd";
if (const char* p = strchr(options, ch)) {
    sym = Arr[p - options];
}

但这有点糟糕。我建议只使用一个开关:

switch (ch) {
    case 'e': sym = e; break;
    case 'a': sym = a; break;
    ...
    default:
        is.unget();
        is.setstate(ios::failbit);
}

另外is >> ch 可能会失败,而您并未对此进行检查。你应该:

istream& operator>>(istream& is, Symbol& sym) {
    char ch;
    if (is >> ch) {
        switch(ch) { ... }
    }
    return is;
}

【讨论】:

  • 但为什么是-4 而不是1? a 在我的代码中出现在 e 之后,我是否误解了 strchr 的工作原理?
  • @GizmoofArabia 你减去了chars。您的枚举无关紧要。
  • @GIzmoofArabia,不。当您执行子结构时,'a' - 'e' 为负数,因为您正在执行 ASCII 代码子结构。看看ASCII codes。查看 dec 和 char 列。
  • 感谢您的帮助,我坚持使用strchr,因为我不确定稍后检查我工作的人是否可以使用switchstrchr 是为此建议的。那么为什么你说你的第一个解决方案是“糟糕的”,你能详细说明一下吗?
  • @GizmoofArabia 因为您只是在检查输入的字符是否是 5 个可能值之一,所以 switch 是执行此类操作的更直接方式。 strchr 在这里推理需要更长的时间......这有点令人困惑。
猜你喜欢
  • 2016-05-14
  • 2014-10-20
  • 2017-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-15
相关资源
最近更新 更多