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; } }