2016-09-06 3 views
1

Я делаю банковскую программу, которая запрашивает несколько входов, таких как номер счета, имя и баланс. Предполагается, что баланс будет равномерно распределен в течение 10 месяцев. Но по какой-то причине, когда я ввожу имя с пробелом между выводами, цикл будет бесконечно. Я думал, что использование getline (cin, name) поможет устранить проблему, но это создаст больше проблем. Ввод некоторых чисел также вызывает бесконечный цикл.Почему мой выход бесконечно зацикливается?

#include <iostream> 
#include <iomanip> 
#include <string> 
using namespace std; 

void displayColumnTitle() { 
    cout << "MONTH BALANCE DUE" << endl; 
} 
float calculateBalanceDue(float balanceDue, float paymentAmt) { 
    balanceDue = balanceDue - paymentAmt; 
    return balanceDue; 
} 

void displayBalance(int month, float balanceDue) { 
     cout << left << setw(10) << month << right << setw(7) 
      << setiosflags(ios::fixed) << setprecision(2) << balanceDue << endl; 
} 

int main() { 
    float accountNumber = 0; 
    float balanceDue, paymentAmt; 
    int month = 1; 
    string name; 

    while (accountNumber != -1) 
    { 
     cout << "Enter Account Number(-1 to terminate the input):" << endl; 
     cin >> accountNumber; 
     if (accountNumber == -1) { 
      break; 
     } 
     cout << "Enter name: "; 
     getline(cin, name); 
     cout << "\nEnter balance due:" << endl; 
     cin >> balanceDue; 
     cout << "\nAccount Number: " << accountNumber << endl 
      << "Name: " << name << endl << endl; 
     displayColumnTitle(); 
     paymentAmt = balanceDue * .10; 
     while (balanceDue != 0) { 
      balanceDue = calculateBalanceDue(balanceDue, paymentAmt); 
      displayBalance(month, balanceDue); 
      month++; 
     } 
    } 
    return 0; 
} 

Приносим извинения за беспорядочный код, поскольку я новичок.

+2

Вы уверены, что 'accountNumber' должен быть переменной с плавающей запятой? На самом деле это не имеет особого смысла. –

+1

Кроме того, из-за того, что значения с плавающей запятой работают на компьютерах, почти все операции с значениями с плавающей запятой приведут к ошибкам округления, которые усугубят больше операций, которые вы выполняете. Это означает, что вы можете получить * закрыть * до нуля для 'balanceDue', но не точно равным нулю. Пожалуйста, прочитайте [«Сбита с плавающей запятой?»] (Http://stackoverflow.com/questions/588004/is-floating-point-math-broken). –

+0

oops you right it should int int – blionzion

ответ

1

При вводе некоторых входных данных, которые не могут быть разобраны как число с плавающей точкой, то входной оператор >> не удалит вход из буферов. Поэтому в следующий раз, когда вы попытаетесь прочитать ввод, он будет точно таким же, и вы не сможете его прочитать.

Неспособность читать и анализировать ввод вызовет потоки fail бит для установки, которые могут быть проверены с помощью потока в логическое выражение, как

while (!(cin >> accountNumber)) 
{ 
    // Error reading input 
} 

Когда вы не прочитать вход, который необходимо очистить бит fail, а также отбросить остальную часть линии.

Очистка разряда fail осуществляется с помощью the streams clear function, а отбрасывание остаточного ввода на линии осуществляется с помощью the streams ignore function.

Собираем все вместе выше цикл может выглядеть

while (!(cin >> accountNumber)) 
{ 
    // Error reading input 
    cin.clear(); // Clear failure flag 
    cin.ignore(numeric_limits<streamsize>::max(), '\n'); // skip bad input 

    cout << "Error in input, please try entering account number again: "; 
} 

То же самое должно быть сделано для ввода balanceDue.

0

Вы застреваете в бесконечном цикле, потому что balanceDue имеет тип float.

#define delta 1e-10 
paymentAmt = balanceDue * .10; 
while (balanceDue > delta) { 
    balanceDue = calculateBalanceDue(balanceDue, paymentAmt); 
    displayBalance(month, balanceDue); 
    month++; 
} 

Это значение будет очень близко к нулю, но не точно равно нулю. Рассмотрим изменение типа данных balanceDue от float до int.

Редактировать: Если вам не разрешено изменять тип переменной. Затем определите маленький delta. И проверить

while (balanceDue > delta) { 
    //do something 
} 
+0

Спасибо за ввод! Но, к сожалению, я не могу изменить тип, потому что в инструкциях по назначению указано, что он должен быть float :( – blionzion

+1

Затем определите небольшое значение сигмы и оцените «balanceDue». – Ari0nhh

+0

Как [std :: numeric_limits :: epsilon] (http: /en.cppreference.com/w/cpp/types/numeric_limits/epsilon) –

0

Попробуйте принять номер учетной записи пользователя перед циклом while.

Смежные вопросы