我在Windows上写了一个小小的音乐节目以获得乐趣。我发现代码部分出错了。这是用于再现问题的最小化代码(MCVE):
#include <iostream>
using std::istream;
using std::cin;
using std::cout;
using std::cerr; // Debug output goes to stderr
using std::endl;
class Key {
public:
typedef signed char Pitch, Octave; // -128 to 127
typedef signed long Absolute; // -2147M to 2147M
Pitch p;
Octave o;
public:
Key(const Pitch& _p, const Octave& _o) :
p(_p), o(_o) {}
Key(void) : Key(Pitch(0), Octave(0)) {};
Absolute abs(void) const {
return 12L * Absolute(o) + Absolute(p);
}
friend istream& operator>> (istream&, Key&);
};
istream& operator>> (istream& is, Key& k){
return (is >> k.p >> k.o);
}
这是正在运行的部分:
Key k;
cin >> k;
cout << k.abs() << endl;
给定输入0 0
,输出应该是0
,但实际输出非常大(624
)。我试过这个
cerr << k.p << k.o << endl;
输出为00
(两者之间没有空格,请参阅代码),正如预期的那样。
答案 0 :(得分:1)
is >> k.p
具有特殊行为,因为k.p
具有字符类型。输入0
将生成字符'0'
,而不是值0
。在技术术语中,当右侧参数具有字符类型时,std::istream::operator>>
的重载具有这种不同的行为。
因此,ASCII系统上的输入0 0
将生成恰好为48 * 12 + 48
的输出624
。
您可能希望读入一个int变量,然后转换为k.p
的范围(在超出范围的情况下进行一些错误处理)。