Reputation: 37287
I wrote a small music program on Windows for fun. I found the part of code going wrong. This is the minimized code (MCVE) for reproducing the problem:
#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);
}
And here's the running part:
Key k;
cin >> k;
cout << k.abs() << endl;
Given the input 0 0
, the output is supposed to be 0
, but the actual output is ridiculously big (624
). I tried this
cerr << k.p << k.o << endl;
And the output is 00
(no space between, see code), as expected.
Upvotes: 1
Views: 26
Reputation: 141628
is >> k.p
has special behaviour because k.p
has character type. The input 0
will generate the character '0'
, not the value 0
. In technical terms, the overload of std::istream::operator>>
has this different behaviour when the right-hand argument has character type.
So input 0 0
on an ASCII system would generate output 48 * 12 + 48
which happens to be 624
.
You probably want to read into an int variable and then convert to the range of k.p
(with some error handling in case of out-of-range input).
Upvotes: 1