2

次のコードを実行し、ゴルフ構造の入力を求められたときに新しい行を挿入すると(Enterキーを押す)、関数の2回目の呼び出しは入力を要求せず、Enterキーをもう一度押したかのように終了します。

cin.get()、cin.clear()、cin.ignore(...)を読みましたが、何も役に立たないようです。

複数の.cppファイルとヘッダーとは何の関係もないと確信していますが、コードはそのままにしています。

Visual Studio C++2010-Expressを使用しています。

よろしくお願いします!

ヘッダーファイル:golf.h

#ifndef GOLF_H
#define GOLF_H

const int Len = 40;

struct golf{

    char fullname[Len];
    int handicap;

};

int setgolf(golf & g );
void showgolf(const golf & g );

#endif

Golf.cpp

#include "stdafx.h"
#include "golf.h"
#include <iostream>
#include <string>


using namespace std;

int setgolf(golf & g ){

    cout << "Enter a name for the golf structure:" << endl;
    if  (cin.get(g.fullname,Len)) {     
        cin.get(); // deals with the '\n' incase the user inputs a valid string
        return 1;
    }
    else{
        return 0;
    }

}
void showgolf(const golf & g ){

    cout << "this golf structure contains the following information:" << endl;
    cout << "name:      " << g.fullname << endl ;
    cout << "handicap:  " << g.handicap << endl ;

}

主要 ()

#include "stdafx.h"
#include "golf.h"
#include <iostream>
#include <string>


using namespace std;

int main()
{

    golf myGolf;

    // check of int setgolf(golf & g );
    int answ = setgolf(myGolf); //try to input empty string
    showgolf(myGolf);
    cout << "the number returned :" << answ << endl ;

    answ = setgolf(myGolf); // normal string
    showgolf(myGolf);
    cout << "the number returned :" << answ << endl ;

    return 0;
}
4

2 に答える 2

2

この問題は、最初のプロンプトで Enter キーを押すだけで発生します。入力ストリームは、エラー状態フラグである eof としてマークされます (これが 0 を返す理由です)。その後、入力ストリームは機能しなくなります。

ISO 1998より前の一種の古いC++を使用しているようですが、それは必要ないと思います。ただし、自分のアプローチに固執したい場合は、次のようにします: after cin.getline()(何も返す必要はありません) write: cin.clear(); cin.sync();、次のように:

void setGolf(Golf &g)
{
    cout << "Enter a name for the golf structure:" << endl;
    getline( cin, g.fullname ) );

    cin.clear();
    cin.sync();
}

次に、コードのモダナイゼーションについてです。まず、標準ライブラリの class を使用できますstring。これは、最大値の char を指定せずに、必要に応じて増加する文字列リテラルを格納できます。そのクラスをインクルードする header をインクルードしているので、これはやや混乱しますがstring、それを使用していません。の使用には、構造string内で発生する可能性のある潜在的なバッファ オーバーフローを自動的に修正するなど、他の利点もありますGolf。だから私はあなたの構造を次のように変更します:

struct Golf{
    string fullname;
    int handicap;
};

getline(), inを使用するとutility、行全体を読み取って に格納しstring、すべての魔法を実行できます。したがって、golf.cppファイルを次のように変更できます。

#include <utility>

//...

void setGolf(Golf &g)
{
    cout << "Enter a name for the golf structure:" << endl;
    getline( cin, g.fullname ) );   
}

また、戻り値の型を に変更できるようになりましたvoid。の使用中に何らかのエラーが発生する可能性はほとんどありませんgetline()。とにかく、bool組み込み型である (boolean 型) をリテラルtruefalse.

main()私はあなたが今、よりシンプルなスタイルに変えることができると確信しています:

int main()
{

    Golf myGolf;

    setGolf(myGolf);
    showGolf(myGolf);

    setGolf(myGolf);
    showGolf(myGolf);

    return 0;
}

最後に、情報を構造体ではなくクラスにカプセル化することを検討できますが、それはまったく別の問題です。

お役に立てれば。

于 2013-02-18T19:49:54.353 に答える