1.
首先cin>>a返回的是左操作数,也就是返回cin。
cin的条件状态中: cin.eof() 判断流是否到达文件的结束符
cin.fail() 判断IO操作是否失败
在while(cin>>a)中看流是否还能用,主要是判断 cin.fail() 的取值。事实上,无论是否用于while循环,流必须处于无错误状态才能用于输入和输出 ,也就是cin.fail() 必须为0值,程序以下的cin操作才能正常执行。
导致cin.fail() 为1的操作有:输入坏值 或 遇到文件结束符(ctrl+z)
当cin.fail() =1时,可以设置cin.clear()将流中的所有状态值设为有效状态,以下操作就会正常输入输出了,否则再遇到cin就不能正常读入赋值。
2.
关于while(cin>>a)中输入值是用 “空格” 间隔还是用 “回车” 间隔的问题:
while(cin)中有个缓冲机制规定,只有收到回车键,才会将所有输入的数据一次提交到输入处理函数cin里,而这个输入过程,在按下回车之前,是不受cin控制的。
对于正常的输入,用回车和空格没有差别,关键是我们最后往往要输入个ctrl+z来结束输入,这里要特别注意,ctrl+z之前必须要按“回车”,不能是空格,也不能什么都不按。
正确的顺序是:“正常值输入(以空格或回车间隔都可以)”、“回车”、(ctrl+z)、“回车”。这样在缓冲机制下while(cin)循环就会把ctrl+z作为输入流单独进行判断,cin.eof()为真,即遇到正常的文件结束符,否则,while(cin)循环判断时以为ctrl+z和之前的空格是一起的或者和之前的其他输入是一起的,认为是输入了坏值,认为没有遇到正常的文件结束符。
这样理解对吗,欢迎批评指正!
PS:在写算法作业时,需要先从文件读入待查询文本,之后还要从不同文件中读入查询。在切换文件时出现问题,用while(cin>>a)判断文件结束后就是切换不了。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e7+10;
string str;
string tmp;
int next[maxn],dp[maxn];
void getnext()
{
memset(next,0,sizeof(next));
int l=tmp.length();
int i=0,j=-1;
next[0]=-1;
while(i<l-1)
{
if(j==-1||tmp[j]==tmp[i])
{
++i;
++j;
next[i]=j;
}
else{
j=next[j];
}
}
}
int kmp()
{
int i=0,j=0;
int l1=str.length();
int l2=tmp.length();
int cnt=1;
while(i<l1&&j<l2)
{
if(j==-1||str[i]==tmp[j])
{
i++;
j++;
}
else
{
j=next[j];
}
if(j==l2-1)
return dp[i-j+1];
}
return -1;
}
int main()
{
freopen("corpus.txt","r",stdin);
while(cin>>tmp)
{
str=str+" "+tmp;
}
/*for(int i=0;i<60;i++)//(用这句话代替上一句话,执行起来是没有问题的 ,但问题是我事先不知道文件里面有多少个字符串)
{
cin>>tmp;
str=str+tmp;
} */
cout<<str<<endl;
fclose(stdin);
// cin.clear(); 一开始不加这句话,执行到while(getline(cin,tmp)就会停止无法再从控制台输入。
int l=str.length();
dp[0]=1;
for(int i=1;i<l;i++)
{
if(str[i]==' ')
dp[i]=dp[i-1]+1;
else
dp[i]=dp[i-1];
}
freopen("CON","r",stdin);
while(getline(cin,tmp))
{
tmp=tmp+" ";
getnext();
int t=kmp();
if(t==-1)
{
cout<<"--"<<tmp<<endl;
}
else cout<<t<<' '<<tmp<<endl;
}
}