我尝试运行以下代码,但在输入一次后,其余输入将初始化为零并自动显示在屏幕上。我哪里出错了?
#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";
}
答案 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');
}