使用 strchr 重载>>
Using strchr to overload >>
我正在尝试重载>>运算符以读取单个(使用 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;
,包括iostream
和cstring
相同。
这里有一些问题。首先,让我们修复您的支撑。只是总是使用牙套。很难看出什么与什么对齐:
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;
}
如果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'.
相关文章:
- 继承函数的重载解析
- 你能重载对象变量名本身返回的内容吗
- 从父命名空间重载类型
- 使用C++中的模板和运算符重载执行矩阵运算
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 重载操作程序时出错>>用于类中的字符串 memebr
- 一个关于在C++中重载布尔运算符的问题
- 不同翻译单元中不可重载的非内联函数定义
- 为什么使用SFINAE而不是函数重载
- 为什么我不能在 C++ 中的特定函数重载中调用同一函数的任何其他重载?
- 将重载的成员函数传递给函数模板
- c++:可变模板和函数重载
- 重载元组索引运算符-C++
- 如何使用重载的相等(==)运算符向测试用例添加描述
- 重载==不适用于二进制树
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 重载运算符new[]的行为取决于析构函数
- 正在尝试重载二进制搜索树分配运算符
- 重载Singly Linked List中的赋值运算符
- 取消引用运算符不能重载