freopen()函数:
FILE *freopen(const char *__restrict__ _Filename, const char *__restrict__ _Mode, FILE *__restrict__ _File)
解释:
@return 返回值为一个指向FILE类型的指针
@param 参数分别为重定向时的文件路径、文件访问模式以及被重定向的流
使用方法:
FILE *fp = freopen(“xx.txt”,“r”,stdin);//将标准输入流重定向到xx.txt。即从xx.txt中获取读入。
第二个参数(模式):
“r” 打开一个用于读取的文件。该文件必须存在。
“w” 创建一个用于写入的空文件。如果文件名称与已存在的文件相同,则会删除已有文件的内容,文件被视为一个新的空文件。
“a” 追加到一个文件。写操作向文件末尾追加数据。如果文件不存在,则创建文件。
“r+” 打开一个用于更新的文件,可读取也可写入。该文件必须存在。
“w+” 创建一个用于读写的空文件。
“a+” 打开一个用于读取和追加的文件。
问题:多次重定向时,为什么第二次未成功重定向?
先上问题代码:
string str;
freopen("1.txt","r",stdin);
while(cin>>str)
{cout<<str;}
freopen("2.txt","r",stdin);
while(cin>>str)
{cout<<str}
运行上方代码,会发现第二个文件(2.txt)里的内容无法被正确读入。甚至根本无法进入while循环。
也由此确立的问题所在:第二个while循环中的判断条件cin>>str就是有问题的。
这时我们在代码中使用cin.rdstate() 来看看cin的状态。
string str;
freopen("1.txt","r",stdin);
while(cin>>str)
{cout<<str;}
//新加部分
if(cin.rdstate() == ios_base::eofbit)
cout<<"已到文件尾部";
freopen("2.txt","r",stdin);
while(cin>>str)
{cout<<str}
这里的eofbit的标识含义就是文件尾部。
都读到文件尾部了,那cin还会继续读吗?定然是不会的。
那即使你重定向到了一个另一个新文件,也没有改变此刻cin的状态,那肯定是读不了另一个文件的了。
解决办法:cin.clear()
经查找,发现cin.clear()并不是字面意思(清空cin的缓冲区之类的),而是改变cin的状态。
cin的状态有以下几种:
- goodbit 无错误
- Eofbit 已到达文件尾
- failbit 非致命的输入/输出错误,可挽回
- badbit 致命的输入/输出错误,无法挽回
cin.clear()默认参数为0即goodbit。所以在第二次重定向时修改一下cin的状态即可。
改后代码:
string str;
freopen("1.txt","r",stdin);
while(cin>>str)
{cout<<str;}
//新加部分
cin.clear();
freopen("2.txt","r",stdin);
while(cin>>str)
{cout<<str}
至此,我遇到的问题就解决了。
PS:清空缓冲区的函数为cin.sync()
以上为本人在网络上查阅总结而得,若是有表达不准确的或是错误的,欢迎评论与指正。