【发布时间】:2015-02-17 04:19:20
【问题描述】:
我正在为 C++ 中的 Fraction 类编写一个重载运算符 >> 的函数。标题是这样的:friend istream& operator>>(istream&, Fraction&);我一直难以满足我为检测非法输入而设置的所有要求。
这是我想要实现的目标:
- 如果用户输入 (int)(enter_key),该函数应将分子设置为 int,分母设置为 1 并返回。
- 如果用户输入(int1)('/')(int2)(enter_key),则设置分子为int1,分母为int2,然后返回。
- 任何不符合前两者的输入形式都会引发异常。
函数是这样调用的:
Fraction fin;
do {
cout << "Enter a fraction here: ";
try {
cin >> fin;
sum += fin;
} catch (FractionException &err) {
cout << err.what() << endl;
}
} while (fin != 0);
我尝试了很多东西,这是我的代码的一个版本。 FractionException 已得到处理:
istream& operator>>(istream& input, Fraction& frac){
int num, den;
char slash = '\0';
//_________________________________
if(!(input >> num)){
input.sync();
throw FractionException("Please enter numbers only.");
}
frac.numer = num;
//_________________________________
if(!(input >> slash)){
input.sync();
throw FractionException("Please enter slash.");
} else if(slash == '\0'){ //useless
frac.denom = 1;
return input;
} else if(slash != '/')
throw FractionException("Illegal character.");
//_________________________________
if(!(input >> den)){
input.sync();
throw FractionException("Please enter numbers only.");
} else if(den == 0) {
throw FractionException("The denominator is 0; illegal entry.");
} else
frac.denom = den;
return input;
}
我尝试将input.sync() 替换为input.clear() 和input.ignore(streamsize, delim),但没有成功。
我正在考虑 input.peek(),但是整数可以超过一位数。
我尝试将 C 字符串与 input.getline(char*, streamsize) 一起使用并遍历字符串以查找“/”,但程序崩溃了。代码如下所示:
int inputSize, slashIndex;
int num, den;
char* line;
char* numStr;
char* denStr;
bool foundSlash(false);
input.getline(line, 1000);
inputSize = strlen(line);
for(int i = 0; i < inputSize; i++) {
if(!isdigit(line[i])) {
if(line[i] == '/'){
slashIndex = i;
foundSlash = true;
goto checkDen;
} else throw FractionException("Non-slash character is entered");
}
}
checkDen:
if(foundSlash){
for(int i = slashIndex + 1; i < inputSize; i++)
if(!isdigit(line[i]))
throw FractionException("Denominator contains non-numbers");
strncpy(numStr, line, slashIndex - 1);
frac.numer = atoi(numStr);
denStr = /*substring from slashIndex + 1 to inputSize*/;
//The strncpy function only copies from index 0
frac.denom = atoi(denStr);
} else {
frac.numer = atoi(line);
frac.denom = 1;
}
另外,在我现在的程序中,输入流有时会在缓冲区中留下字符,这会导致无限循环。
我只是对自己正在做的事情感到困惑,因为似乎没有任何效果,而且我的代码很粗略。任何帮助或提示将不胜感激。
【问题讨论】:
-
您可以直接使用
getline和std::string。无需担心大小废话。还有goto,真的吗?另外,考虑将读取行放入std::stringstream,然后将字符串流解析为istream,但仅限于一行。
标签: c++ c operator-overloading istream