为什么在代码块中执行时会跳过输入用户输入的行?

Why lines gets skipped from entering user input while executing in code blocks?

所以我有这段代码,但我不知道为什么代码中的两行被读取。这两行由下面的注释标记:

   #include <iostream>
   #include<stdio.h>

using namespace std;

class publication{
     char title[20];
     int price;

     public:

     void getdata(){
        cout<< "Enter the price of the book";
        cin>>price;

        cout<< "Enter the title";  #this line 1st
        gets(title);               #this is not running
     }

      void putdata(){
       cout<<price;
       puts(title);
       }

};

class Tape:public publication{
       float play;

       public:

       void getdata(){
         cout<< "Enter play"; #this line 2nd 
         cin>>play;
       }

       void putdata(){
           cout<<endl<<play;
       }
};

int main()
{
    publication p;
    p.getdata();
    p.putdata();

    Tape t;
    t.getdata();
    t.putdata();

    book b;
    b.getdata();
    b.putdata();

}

现在我无法理解为什么我跳过了第 16 行和第 47 行。我检查了语法,一切都很好。这个程序没有错误。我为 C++ 使用代码块和 gnu gcc 编译器。 This is the image

在这张图片中,您可以看到两行有 auto-compiled,但没有输入标题。删除了一些与问题无关的代码行。

这既不是 IDE 的问题,也不是编译器的问题。不要责怪可怜的 CodeBlocks :(

我不知道是什么促使您在程序中使用 gets 和 puts。如果您关心优化,请尝试使用 std::ios::sync_with_stdio(false);cin

也不要使用gets,因为如果不小心,可能会导致缓冲区溢出。请改用 fgets。参见 cplusplus and Whosebug

现在,谈到这个问题,第 16 行和第 47 行看起来被省略的真正原因是因为代码中的打印语句和消息不正确。唯一似乎被跳过的行是 gets(title);。其实什么都执行了。

为什么跳过 gets(title)?

因此,当您将价格输入为 12 时,它实际上以 12\n 的形式存储在输入缓冲区中。现在在读取 12 之后,缓冲区中仍然有 \n,因为 cin 不像 cin.getline 那样读取新行,而 gets 会看到新行作为终止符。参见 gets

所以使用cin.ignore(numeric_limits<streamsize>::max(), '\n');

清除缓冲区

我已经稍微重新格式化了您的代码。见下文。 请注意,我使用 fgets 将新行视为有效字符,并且 \n 包含在标题中。参见 fgets

using namespace std;

class publication {
    char title[20];
    int price;

public:

    void getdata() {
        cout << "Enter the price of the book"<<endl;
        cin >> price;

        cout << "Enter the title" << endl;

        cin.ignore(numeric_limits<streamsize>::max(), '\n');

        fgets(title, 20, stdin);        
    }

    void putdata() {
        cout << "Price is " << price << endl;
        cout << "Title is "<< title;
    }

};

class Tape :public publication {
    float play;

public:

    void getdata() {
        cout << "Enter play"<<endl; 
        cin >> play;
    }

   void putdata() {
        cout << "Play is " << play << endl;
    }
};

int main()
{
    publication p;
    p.getdata();
    p.putdata();

    Tape t;
    t.getdata();
    t.putdata();
}