class ISBN
{
public:
class Invalid{}; // exception class
string get_ISBN() const ;
ISBN(); // default constructor
ISBN( int p1, int p2, int p3, char p4 ); // construct ISBN from parts
ISBN( string full ); // construct ISBN from string
private:
string full_ISBN;
int part1;
int part2;
int part3;
char part4;
void SetFull(); // Builds the full_ISBN from the individual parts
};
This constructor is supposed to take a string containing an ISBN and break out the individual parts and store them into separate integral and character members.
I run it with an example string of "01-0002-003-X" and it works great for the first part. after that, the tmpStream >> iTemp; line always sets iTemp to 1, and causes a run-time error for the cTemp extraction. What am I missing?
*edit* I've stepped through in a debugger and I know that my substringing is grabbing the proper parts from the main string.
Honestly, using stringstrams like that is too excessive. Simple stoi(some_substring) would suffice. Using stream to get a char you already got in a string is... not fine.
line always sets iTemp to 1, and causes a run-time error for the cTemp extraction
Line 20 sets stream in failed state and you never clear it causing all following reads to fail.
Simplified your code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
ISBN::ISBN( std::string full )
{
std::stringstream tmpStream(full);
(tmpStream >> part1).get(); //get() is here to skip '-'
(tmpStream >> part2).get();
(tmpStream >> part3).get();
(tmpStream >> part4);
if(!tmpStream)
std::cout << "reading failed"; //Replace with throw
//Do parts checking, throwing etc...
//You do not really need temporary variables for it,
//as you can operate on members directly without repercussions in constructor
SetFull();
}
Thanks a bunch. I figured there was a better method than screwing around with all the back and forth stream business, but that's what all the examples I found were using so...