while(cin) как выйти из данного цикла

344
07 марта 2018, 07:54

Разбираю калькулятор из книги Страуструпа, лексемы вроде как считывает правильно, но не могу понять как выйти из цикла. Если ввожу ctrl + z выдаёт ошибку.

    using namespace std;
class Token {
public:
    char kind;        // what kind of token
    double value;     // for numbers: a value 
    Token(char ch)    // make a Token from a char
        :kind(ch), value(0) { }
    Token(char ch, double val)     // make a Token from a char and a double
        :kind(ch), value(val) { }
};
//------------------------------------------------------------------------------
Token get_token()    // read a token from cin
{
    char ch;
    cin >> ch;    // note that >> skips whitespace (space, newline, tab, etc.)
    switch (ch) {
        //not yet   case ';':    // for "print"
        //not yet   case 'q':    // for "quit"
    case '(': case ')': case '+': case '-': case '*': case '/':
        return Token(ch);        // let each character represent itself
    case '.':
    case '0': case '1': case '2': case '3': case '4':
    case '5': case '6': case '7': case '8': case '9':
    {
        cin.putback(ch);         // put digit back into the input stream
        double val;
        cin >> val;              // read a floating-point number
        return Token('8', val);   // let '8' represent "a number"
    }
    default:
        error("Bad token");
    }
}
vector<Token> tok; 
int main()
{
    while (cin) {
        Token t = get_token();
        tok.push_back(t);
        //cout << 1 << endl;
    }
    for (int i = 0; i<tok.size(); ++i) {
        if (tok[i].kind == '*') {    // we found a multiply!
            double d = tok[i - 1].value*tok[i + 1].value;
            // now what?
        }
    }
    return 0;
}
Answer 1

Неохота расписать ошибки, просто смотрите внимательно и сравните

using namespace std;
//тут лучше определить конструктор по умолчанию тоже
class Token {
public:
    char kind;        // what kind of token
    double value;     // for numbers: a value
    Token(char ch = ' ')  // здесь!!!  // make a Token from a char
        :kind(ch), value(0) { }
    Token(char ch, double val)     // make a Token from a char and a double
        :kind(ch), value(val) { }
};
//------------------------------------------------------------------------------
Token get_token()    // read a token from cin
{
    Token t;
    char ch;
    cin >> ch;    // note that >> skips whitespace (space, newline, tab, etc.)
    switch (ch) {
    //not yet   case ';':    // for "print"
    //not yet   case 'q':    // for "quit"
    case '=':
    case '(': case ')': case '+': case '-': case '*': case '/':
        return Token(ch);        // let each character represent itself
    case '.':
    case '0': case '1': case '2': case '3': case '4':
    case '5': case '6': case '7': case '8': case '9':
    {
        cin.putback(ch);         // put digit back into the input stream
        double val;
        cin >> val;              // read a floating-point number
        return Token('8', val);   // let '8' represent "a number"
    }
    default:
        cerr << "Bad token";
    }
    return Token(ch);
}
int main()
{        
    vector<Token> tok;        
    while (cin ) {
        Token t = get_token();
        tok.push_back(t);                        
        //из цикла выходить нужно  вводя EOF (у меня это  ctrl + z )
       //  if (t.kind == '=') break;
       }
    for (size_t i = 0; i<tok.size(); ++i) {
        if (tok[i].kind == '*') {    // we found a multiply!
            double d = tok[i - 1].value*tok[i + 1].value;
            // now what? 
            cout << d;  
            break;      
        }
    }
    return 0;
} 
  • из цикла нужно выходить вводя символ EOF(конец ввода): в моей системе это ctrl+z. Из цикла можно выходить также определив удобный для себя символ - например символ '=' что я и написал в цикле как комментарий
Answer 2
Token get_token()    // read a token from cin
{
    char ch;
    cin >> ch;    // note that >> skips whitespace (space, newline, tab, etc.)
    switch (ch) {
        //not yet   case ';':    // for "print"
    case 'q': 
         cin.setstate(std::ios_base::failbit);
         return Token(ch);   // for "quit"
    case '(': case ')': case '+': case '-': case '*': case '/':
        return Token(ch);        // let each character represent itself
    case '.':
    case '0': case '1': case '2': case '3': case '4':
    case '5': case '6': case '7': case '8': case '9':
    {
        cin.putback(ch);         // put digit back into the input stream
        double val;
        cin >> val;              // read a floating-point number
        return Token('8', val);   // let '8' represent "a number"
    }
    default:
        error("Bad token");
    }
}
vector<Token> tok; 
int main()
{
    while (cin) {
        Token t = get_token();
        if (!cin)
            break;
        tok.push_back(t);
        //cout << 1 << endl;
    }
    for (int i = 0; i<tok.size(); ++i) {
        if (tok[i].kind == '*') {    // we found a multiply!
            double d = tok[i - 1].value*tok[i + 1].value;
            // now what?
        }
    }
    return 0;
}

Я не компилировал не проверял, может опечатался где или точку с запятой забыл.

READ ALSO
Создать новый стек со значениями из другого стека

Создать новый стек со значениями из другого стека

Создать стек с числами в диапазоне от –50 до +50После создания стека выполнить индивидуальное задание

418
Перевод из десятичной СС в двоичную

Перевод из десятичной СС в двоичную

Добрый день, есть такой код, переводящий число из 10-й системы в 2-ю

363
CRT (c++) и unit test

CRT (c++) и unit test

Я недавно узнал, что можно проверять программу на предмет утечки памяти через метод _CrtDumpMemoryLeaks();Т

367
Поиск по ListActivity

Поиск по ListActivity

Как добавить ActionBar в ListActivity и сделать в нем SearchWidget, вернее выполнить поиск элементов по списку(как поиск в плей маркете)?

350