此代码运行不正常

时间:2016-01-12 06:57:12

标签: c++

我尝试运行以下代码,但在输入一次后,其余输入将初始化为零并自动显示在屏幕上。我哪里出错了?

#include<iostream>
#define N 50
using namespace std;

struct movies_t
{
    char title[60];
    int year;
}user[N];

void printmovie(movies_t);

int main()
{

    for(int i = 0; i < N; i++)
    {
        cout << "Enter title: ";
        cin.get(user[i].title, 60);
        cout << "Enter year: ";
        cin >> user[i].year;
   }

   cout << "\nYou have entered these movie: \n";
   for(int i = 0; i < N; i++)
        printmovie(user[i]);
   return 0;
}

void printmovie(movies_t m)
{
     cout << m.title;
     cout << " (" << m.year << ")\n";
}

2 个答案:

答案 0 :(得分:1)

问题在于,当您输入第一部电影的年份后按Enter键时,输入(换行符)仍在输入缓冲区中,因此当您下次呼叫apple mango mango apple mango grapes 时,它将读取该换行符并认为您进入空行。

您需要将cin.get(...)告诉ignore该行的其余部分,包括换行符。

答案 1 :(得分:1)

执行

cin >> user[i].year;

换行符仍留在输入流中。

下次执行

cin.get(user[i].title, 60);

遇到的第一个字符是换行符。发生这种情况时,failbit设置为cin。以下是http://en.cppreference.com/w/cpp/io/basic_istream/get(强调我的)的一些信息:

  

4)读取字符并将它们存储到s指向其第一个元素的字符数组的连续位置。提取并存储字符,直到出现以下任何一种情况:

     
      
  • 已存储n-1个字符

  •   
  • 文件结束条件发生在输入序列中(setstate(eofbit)被调用)

  •   
  • 下一个可用输入字符c等于delim,由Traits::eq(c, delim)确定。不提取此字符(与basic_istream::getline()不同)

  •   
     

如果未提取任何字符,请致电setstate(failbit) 。在任何情况下,如果count>0,则空字符(CharT())存储在数组的下一个连续位置。

设置failbit cin后,从cin读取任何内容,直到通过显式调用cin.clear()清除状态。

由于您没有任何代码来检查cin的状态并在适当时清除状态,因此在第一次迭代后循环中不会读取任何内容。

解决问题的一种方法是在读取年份后添加一行来忽略流的内容。

cin >> user[i].year;
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

此外,最好在执行IO操作后始终检查流的状态,以确保不会忽略任何错误。

for(int i = 0; i < N; i++)
{
   cout << "Enter title: ";
   cin.get(user[i].title, 60);
   if ( !cin )
   {
      cout << "Error reading title.\n";
      exit(1);
   }

   cout << "Enter year: ";
   cin >> user[i].year;
   if ( !cin )
   {
      cout << "Error reading name.\n";
      exit(1);
   }

   // Ignore everything up to and including the newline character.
   cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}