web-dev-qa-db-ja.com

cinの後にgetline(cin、s)を使用する

ユーザー入力の全行を取得して文字列名に入れるには、次のプログラムが必要です。

_cout << "Enter the number: ";
int number;
cin >> number;

cout << "Enter names: ";
string names;

getline(cin, names);
_

ただし、getline()コマンドの前に_cin >> number_コマンドを使用すると(これが問題だと推測します)、名前を入力できません。どうして?

cin.clear()コマンドについて聞いたことがありますが、これがどのように機能するのか、なぜこれが必要なのかさえわかりません。

37
pauliwago
_cout << "Enter the number: ";
int number;
if (cin >> number)
{
    // throw away the rest of the line 
    char c;
    while (cin.get(c) && c != '\n')
        if (!std::isspace(c))
        {
            std::cerr << "ERROR unexpected character '" << c << "' found\n";
            exit(EXIT_FAILURE);
        }
    cout << "Enter names: ";
    string name;
    // keep getting lines until EOF (or "bad" e.g. error reading redirected file)...
    while (getline(cin, name))
        ...use name...
}
else
{
    std::cerr << "ERROR reading number\n";
    exit(EXIT_FAILURE);
}
_

上記のコードでは、このビット...

_    char c;
    while (cin.get(c) && c != '\n')
        if (!std::isspace(c))
        {
            std::cerr << "ERROR unexpected character '" << c << "' found\n";
            exit(EXIT_FAILURE);
        }
_

...数値に空白のみが含まれた後、入力行の残りをチェックします。

なぜ無視を使用しないのですか?

それはかなり冗長なので、ストリームで_>> x_の後にignoreを使用することは、次の改行までコンテンツを破棄するための推奨される代替方法ですが、空白以外のコンテンツを破棄するリスクがあります、ファイル内の破損データを見落とす。ファイルのコンテンツが信頼できるかどうか、破損したデータの処理を回避することの重要性などに応じて、気にすることも気にしないこともあります。

では、いつクリアと無視を使用しますか?

したがって、std::cin.clear()(およびstd::cin.igore())はこれには必要ありませんが、エラー状態を除去するのに役立ちます。たとえば、ユーザーに有効な番号を入力する機会を多く与えたい場合。

_int x;
while (std::cout << "Enter a number: " &&
       !(std::cin >> x))
{
    if (std::cin.eof())
    {
        std::cerr << "ERROR unexpected EOF\n";
        exit(EXIT_FAILURE);
    }

    std::cin.clear();  // clear bad/fail/eof flags

    // have to ignore non-numeric character that caused cin >> x to
    // fail or there's no chance of it working next time; for "cin" it's
    // common to remove the entire suspect line and re-Prompt the user for
    // input.
    std::cin.ignore(std::numeric_limits<std::streamsize>::max());
}
_

Skipwsなどでもっと簡単にできないでしょうか?

元の要件に対するignoreに代わるもう1つの単純だが中途半端な選択肢は、_std::skipws_を使用して、行を読み取る前に空白をスキップすることです...

_if (std::cin >> number >> std::skipws)
{
    while (getline(std::cin, name))
        ...
_

...ただし、「1E6」のような入力を取得した場合(たとえば、一部の科学者が1,000,000を入力しようとしたが、C++は浮動小数点数の表記のみをサポートしている場合)、それを受け入れない場合、number setになります_1_、および_E6_をnameの最初の値として読み取ります。それとは別に、有効な番号の後に1つ以上の空白行がある場合、それらの行は黙って無視されます。

10
Tony Delroy
cout << "Enter the number: ";
int number;
cin >> number;

cin.ignore(256, '\n'); // remaining input characters up to the next newline character
                       // are ignored

cout << "Enter names: ";
string names;
getline(cin, names);
19

それを行う別の方法は、

_cin.ignore ( std::numeric_limits<std::streamsize>::max(), '\n' ); 
_

_cin>>number;_の後、入力バッファを完全にフラッシュします(改行が見つかるまで余分な文字をすべて拒否します)。 max()メソッドを取得するには、_#include <limits>_が必要です。

17
jonsca

試してください:

int number;

cin >> number;

char firstCharacterOfNames;
cin >> firstCharacterOfNames;  // This will discard all leading white space.
                               // including new-line if there happen to be any.

cin.unget();                   // Put back the first character of the name.

std::string  names;
std::getline(cin, names);      // Read the names;

代わりに。番号と名前が常に異なる行にあることがわかっている場合。

cin >> number;
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 
std::getline(cin, names);
9
Martin York

Getlineを使用する前に、std :: wsを使用して入力バッファー内の空白文字を抽出できます。 std :: wsのヘッダーはsstreamです。

cout << "Enter the number: ";
int number;
cin >> number;
cout << "Enter names: ";
string names;
cin>>ws;
getline(cin, names);
5
Rajeev Atmakuri

Getline()関数の前にcinを使用する場合はcin.ignore()を試してください

void inputstu(){
    cout << "Enter roll Number:";
    cin >> roll_no;
    cin.ignore(); //ignore the withspace and enter key
    cout << "Enter name:";
    getline(cin, stu_name);
}
2
Vishal Rai
cout << "Enter the number: ";
int number;
cin >> number;

cout << "Enter names: ";
string names;
getline(cin, names);//works on the \n left behind
getline(cin, names);//continues and rewrites names

かなり自己説明的で、ストリームにはcin >> numberは、最初に使用されたときに名前に割り当てられます。 getlineを再利用すると、正しい値が書き込まれます。

1

または、入力バッファをフラッシュして文字列を読み取ることができます

fflush(stdin)

ヘッダーstdio.hで定義されています。

このコードは機能します。

cout << "Enter the number: ";
int number;
cin >> number;

cout << "Enter names: ";
string names;
fflush(stdin);  //FLUSHING STDIN
getline(cin, names);
1
pz64_

必要な答えは cppreference で見つけることができます。

空白で区切られた入力の直後に使用した場合、例えば_int n; std::cin >> n;_の後、getlineは入力ストリームに残されたendline文字をoperator >>で消費し、すぐに戻ります。一般的な解決策は、cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');を使用して入力行の残りの文字をすべて無視してから、行指向の入力に切り替えることです。

0
shuaihanhungry
cout << "Enter the number: ";

int number;
cin >> number;

getc(stdin);  //you need add this line 

cout << "Enter names: ";

string names;

getline(cin, names);
0
H R shuvo

概念的には、各回答をきちんと1行にする必要があると思います。では、なぜこれを試してみませんか?

cout << "Enter the number: ";
string line;
getline(cin, line);
int number = std::stoi(line);

cout << "Enter names: ";
string names;
getline(cin, names);

コードは最初の改行文字を正しく消費し、行が正しい場合は番号を返し、正しくない場合は例外をスローします。すべて無料!

0
ngọcminh.oss

cinでint変数を取得した後、バッファーに残っている「\ n」を無視するため、cinステートメントの後にcin.ignore()を使用します。

私は同様の問題で使用した同様のプログラムを持っています:

#include <iostream>
#include <iomanip>
#include <limits>

using namespace std;

int main() {
    int i = 4;
    double d = 4.0;
    string s = "HackerRank ";

    // Declare second integer, double, and String variables.
    int n;
    double d2;
    string str;

    // Read and save an integer, double, and String to your variables.
    cin >> n;
    cin >> d2;

    cin.ignore();

    getline(cin, str);

    // Print the sum of both integer variables on a new line.
    cout << i + n << endl;


    // Print the sum of the double variables on a new line.
    cout << d + d2 << endl;

    // Concatenate and print the String variables on a new line
    cout << s << str << endl;

    // The 's' variable above should be printed first.

    return 0;
}
0
lopezdp

私はちょうど使用しました

getline(cin >> ws,lard.i_npute);

標準で

#include <iostream>

キャリッジリターンで問題が発生し、wsマニピュレーターが機能した場合のヘッダー。おそらく、ループ関数をクラスとして埋め込み、コンストラクターとデストラクターの呼び出しを少なくとも使用し始めるでしょう。

0
1911 Soldier