1. ホーム
  2. c++

[解決済み] C++のstd::cinオブジェクトのルールは何ですか?

2022-03-12 20:24:35

質問

C++の学習の練習と、その機能としてMLAの引用文作成機能(数十の引用文がある大きな論文を書いています)を個人的に使うために、小さなプログラムを書いています。

私はクラスや他の.cppファイルをmainの中で使用することを理解していないので、わざわざ私に言わないでください。もっと時間があれば、これを再利用されるコードごとの関数に分解するかもしれません。

質問ですが、std::cinオブジェクトはどのように動作するのでしょうか?現在、一語と思われる文字列には std::cin >> で読み込み、スペースを含む文字列には getline(std::cin, string) で読み込んでいます。しかし、私は正しい出力を得ていません。私はただ、std::cinがどのように動作するのか、また、なぜ予期せずいくつかの入力をスキップし続けるのかを知りたいだけです(例えば、webPageに入力するチャンスを与える代わりに、webPageをスキップしてしまいます)。

void webCit() {
    std::cout << "Leave any unknowns blank.\n";

    std::cout << "Author last name: ";
    std::string lastName;
    std::cin >> lastName;

    if (lastName.size() != 0) {
        lastName = lastName + ", ";
    }


    std::cout << "Author first name: ";
    std::string firstName;
    std::cin >> firstName;

    if (firstName.size() != 0) {
        firstName = firstName + ". ";
    }


    std::cout << "Article title: ";
    std::string articleTitle;
    getline(std::cin, articleTitle);

    if (articleTitle.size() != 0) {
        articleTitle = "\"" + articleTitle + ".\" ";
    }

    std::cout << "Title of web page: ";
    std::string pageTitle;
    std::cin >> pageTitle;

    if (pageTitle.size() != 0) {
        pageTitle = pageTitle + ". ";
    }

    std::cout << "Publication date: ";
    std::string publicationDate;
    getline(std::cin, publicationDate);

    if (publicationDate.size() != 0) {
        publicationDate = publicationDate + ". ";

    }

    std::cout << "Web address: ";
    std::string webAddress;
    getline(std::cin, webAddress);

    webAddress = "<" + webAddress + ">. ";

    std::cout << "Date accessed: ";
    std::string dateAccessed;
    getline(std::cin, dateAccessed);

    if (dateAccessed.size() != 0) {
        dateAccessed = dateAccessed + ". ";
    }

    std::string citation =
        lastName + firstName + articleTitle + pageTitle + publicationDate + webAddress + dateAccessed;

    std::cout << citation; //TEST; remove after
}

編集:I/O

Leave any unknowns blank.
Author last name: Hooked
Author first name: Jerbear
Article title: Title of web page: title
Publication date: Web address: www.win.com
Date accessed: 4/29/09
Hooked, Jerbear. Title. <www.win.com>. 4/29/09. 

見ての通り、私の入力はスキップされてしまうので、何かが間違っています。

どうすればいいですか?

ここで起こっていることは std::cin >> firstName; までしか読み取れません。 を含まない は、最初の空白文字で、改行を含む(または '\n' を入力したとき、その時点では getline(std::cin, articleTitle); , '\n' の次の文字であることに変わりはありません。 std::cin であり、かつ getline() はすぐに返されます。

// cin = "Bloggs\nJoe\nMan of Steel, Woman of Kleenex\n"
std::cin >> lastName;
std::cin >> firstName;
// firstName = "Joe", lastName = "Bloggs", cin = "\nMan of Steel, Woman of Kleenex\n"
getline(std::cin, articleTitle);
// articleTitle = "", cin = "Man of Steel, Woman of Kleenex\n"

を追加する ' std::cin >> std::ws ' ( ws 意味 w 灰色 s ペース) を呼び出す前に、getline() を呼び出すと問題が解決します。

std::cin >> firstName >> std::ws;
getline(std::cin, articleTitle);

でも、引数でやったほうが、どこでミスったのかわかりやすい。

std::cin >> firstName;
getline(std::cin >> std::ws, articleTitle);