7
int x=0;
string fullname = "";
float salary;
float payincrease;
float newsal;
float monthlysal;
float retroactive;
while(x<3){
    cout << "\n What is your full name?";
    cin >> fullname;
    cout << "\n What is your current salary? \t";
    cin >> salary;
    cout << "\n What is your pay increase? \t";
    cin >> payincrease;
    newsal = (salary*payincrease)+salary;
    monthlysal = newsal/12.00;
    retroactive = (monthlysal*6)-(salary/2);
    cout << "\n" << fullname << "'s SALARY INFORMATION";
    cout << "\n New Salary \t Monthly Salary \t Retroactive Pay";
    cout << "\n \t" << newsal << "\t" << monthlysal << "\t" << retroactive;
    x++;
}

私のループは、cin が要求されるたびに停止するようには見えず、代わりにループを即座に 3 回単独で実行します。入力が求められたときに停止するにはどうすればよいですか?

4

3 に答える 3

12

cin を呼び出したときに入力ストリームが空でない場合、cin はユーザーからの追加を待つ代わりに、既にバッファーにあるデータを使用します。抽出演算子を使用しているため、cin が変数に値を送信するときに、バッファ内の先頭の空白をスキップし、次の空白で停止します。

この行にブレークポイントを置きます。

cout << "\n What is your current salary? \t";

プログラムを実行し、Bob Smith と入力します。ブレークポイントに到達したら、文字列のフルネームの上にカーソルを置きます。「Bob Smith」ではなく「Bob」のみが格納されていることがわかります。「Bob Smith」はバッファーに入れられましたが、抽出演算子で cin を使用すると、先頭の空白をスキップし、次の値を変数に入れ、次の空白で停止します。これを実証するために、これを実行してみてください:

#include <iostream>
#include <string>
using namespace std;
int main()
{
    string str1,str2;
    cin >> str1;
    cin >> str2;
    cout << str1 << " " << str2 << "\n\n";
    return 0;
}

「Bob Smith」と入力すると、cin を 2 回呼び出しても、入力は 1 回だけです。ただし、"Bob" と "Smith" の両方が文字列 str1 と str2 に取り込まれていることがわかります。

したがって、cin が Bob と Smith の間のスペースに達すると、string fullname の入力を停止すると結論付けることができます。cin の次の呼び出しでは、バッファーにはまだ "Smith" が含まれているため、ユーザーからさらに入力を受け取る代わりに、変数の給与に "Smith" を入力しようとします。明らかに、これはあなたがしたいことではありません。cin を使用するたびに前にフラッシュを呼び出して cin で無視してバッファーを消去するか、代わりにロジックを修正して getline を使用して、スペースを含む完全な名前を取得することができます。

問題を解決するには、cin >> の代わりに getline を使用するだけなので、次の行を置き換えます。

cin >> fullname;

これとともに:

getline(cin,fullname,'\n');

次に、while ループを使用して一連のアクションを特定の回数実行しています。これは通常、for ループを使用するものです。

余談ですが、デバッグに役立つ小さな入力検証ループを記述したり、無効な入力を変数に入れようとすることを回避したりすることもできます ("Smith" を浮動小数点数にするなど)。このようなものはうまくいくかもしれません:

for(;;)
{
    if(cin >> salary)
        break;
    cin.clear();
    cin.ignore(INT_MAX,'\n');
}

cin は値を返すため、if ステートメントで使用できることに注意してください。有効な入力を取得すると、true が返されます。そうでない場合は false を返します。より明確にするために、if ステートメントを使用せずに通常の cin 呼び出しを使用して、cin.good() をチェックすることもできます。これは基本的に同じ正味の効果になります。Visual Studio を使用しておらず、INT_MAX に関するエラーが発生した場合は、解決するために #include limits.h が必要になる場合があります。

于 2012-09-05T00:03:12.087 に答える
5

charこれは、anintが期待される場所にa を入力した場合に発生します。

と を使用 cin.clear();cin.ignore(numeric_limits<streamsize>::max(), '\n');て、入力を のみに制限しますint

それ以外は、正しいデータ型を入れればスキップしません。

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



int main(void)
{


    int x=0;
    string fullname = "";
    float salary;
    float payincrease;
    float newsal;
    float monthlysal;
    float retroactive;

    while(x<3)
    {
        cout << "\n What is your full name?";
        cin >> fullname;
    cin.ignore( 1000, '\n' );

        cout << "\n What is your current salary? \t";
        cin >> salary;
    cin.clear();
    cin.ignore(numeric_limits<streamsize>::max(), '\n');

        cout << "\n What is your pay increase? \t";
        cin >> payincrease;
    cin.clear();
    cin.ignore(numeric_limits<streamsize>::max(), '\n');

        newsal = (salary*payincrease)+salary;
        monthlysal = newsal/12.00;
        retroactive = (monthlysal*6)-(salary/2);
        cout << "\n" << fullname << "'s SALARY INFORMATION";
        cout << "\n New Salary \t Monthly Salary \t Retroactive Pay";
        cout << "\n \t" << newsal << "\t" << monthlysal << "\t" << retroactive;
        x++;
    }


      cout<<" \nPress any key to continue\n";
      cin.ignore();
      cin.get();

   return 0;
}
于 2012-09-05T04:46:37.240 に答える