Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C++; 我正在编写一个函数,它在C++中为一个分数类重载运算符>。标题如下:friend-istream&operator>>(istream&,france&)我一直很难满足检测非法输入的所有要求_C++_C_Operator Overloading_Istream - Fatal编程技术网

在C++; 我正在编写一个函数,它在C++中为一个分数类重载运算符>。标题如下:friend-istream&operator>>(istream&,france&)我一直很难满足检测非法输入的所有要求

在C++; 我正在编写一个函数,它在C++中为一个分数类重载运算符>。标题如下:friend-istream&operator>>(istream&,france&)我一直很难满足检测非法输入的所有要求,c++,c,operator-overloading,istream,C++,C,Operator Overloading,Istream,以下是我想要实现的目标: 如果用户输入(int)(输入_键),函数应将分子设置为int,分母设置为1并返回 如果用户输入(int1)(“/”)(int2)(输入_键),则将分子设置为int1,分母设置为int2,然后返回 任何形式的输入如果不符合前两种格式,都会引发异常 函数的调用方式如下: Fraction fin; do { cout << "Enter a fraction here: "; try { cin >> fin;

以下是我想要实现的目标:

  • 如果用户输入(int)(输入_键),函数应将分子设置为int,分母设置为1并返回
  • 如果用户输入(int1)(“/”)(int2)(输入_键),则将分子设置为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);
    
    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;
    }
    
    我尝试将
    input.sync()
    替换为
    input.clear()
    input.ignore(streamsize,delim)
    ,但没有成功

    我考虑的是input.peek(),但和整数的长度可以超过一位数

    我试图将C字符串与
    input.getline(char*,streamsize)
    一起使用,并在字符串中循环查找“/”,但程序崩溃了。代码如下所示:

    Fraction fin;
    do {
        cout << "Enter a fraction here: ";
        try {
            cin >> fin;
            sum += fin;
        } catch (FractionException &err) {
            cout << err.what() << endl;
        }
    } while (fin != 0);
    
    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;
    }
    
    int inputSize,slashIndex;
    int num,den;
    字符*行;
    char*numStr;
    char*denStr;
    bool-foundSlash(假);
    input.getline(第1000行);
    inputSize=strlen(行);
    for(int i=0;i
    另外,在我现在的程序中,输入流有时会在缓冲区中留下字符,这会导致无限循环


    我只是对我正在做的事情感到困惑,因为似乎什么都不管用,我的代码也很粗略。任何帮助或提示都会被理解。

    < P>你的职责分工对于C++来说是不正常的。你通常希望<代码>操作符> <代码>来设置一个失败状态(或者在调用设置这种状态的流操作时,或者隐式地使用<代码> > StStest),然后,调用方应该控制是否希望流引发异常。下面是一个例子:

    #include <iostream>
    #include <sstream>
    #include <limits>
    #include <cassert>
    
    struct X { int a_, b_; };
    
    std::istream& operator>>(std::istream& is, X& x)
    {
        char c;
        if (is >> x.a_ && is.get(c))
            if (c == '\n')
                x.b_ = 1;
            else if (!(c == '/' && is >> x.b_))
                is.setstate(std::istream::failbit);
        return is;
    }
    
    int main()
    {
        std::istringstream iss("5\n10/2\n3xyz\n8/17\n9\nNOWAY\n42/4\n");
        X x;
        while (iss >> x)
            std::cout << "parsed " << x.a_ << '/' << x.b_ << '\n';
        iss.clear();
    
        std::string remnants;
        assert(getline(iss, remnants));
        std::cout << "parsing failed, line remnants for '" << remnants << "'\n";
        // normally would prefer following to getline above...
        // iss.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    
        iss.exceptions(std::istream::failbit);
        while (iss)
            try
            {
                while (iss >> x)
                    std::cout << "also parsed " << x.a_ << '/' << x.b_ << '\n';
            }
            catch (const std::exception& e)
            {
                std::cout << "caught exception " << e.what() << '\n';
                if (!iss.eof())
                {
                    iss.clear();
                    iss.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
                }
            }
        std::cout << "eof " << iss.eof() << ", bad " << iss.bad()
             << ", fail " << iss.fail() << '\n';
    }
    
    请参阅在ideone.com上运行

    is>>x.a&&is.get(c)
    中,第一个使用
    >
    流式传输,它将跳过前导空格,但是
    get()
    被用来潜在地读取换行符:这意味着例如
    “10/2”
    “39”
    不被认为是有效的输入:如果您想支持这样的内部和/或尾随空格,考虑:

    std::istream& operator>>(std::istream& is, X& x)
    {
        std::string line;
        if (getline(is, line))
        {
            std::istringstream iss(line);
            char c;
            x.b_ = 1; // default
            if (!(iss >> x.a_) ||
                (iss >> c) && (!(c == '/' && iss >> x.b_)))
                is.setstate(std::istream::failbit);
        }
        return is;
    }
    

    您可以将
    getline
    直接与
    std::string
    一起使用。不必担心大小的废话。也转到
    ,真的吗?此外,考虑将读行放进<代码> STD::StrugSuth,然后将StrueFipe解析为一种<代码> ISTRAM< <代码>,但仅限于一行。谢谢!这很有帮助@USSRe36631:不客气——可以看到你投入了大量的工作,而且它不是特别容易,也不是像在C++中那样有基础的,因为我很乐意写这个代码…