标准IO库问题

编程小新手 2014-04-01 10:14:42
最近在看C++ primer,做了书上的题目,遇到了点问题,程序如下:

#include <string>
#include <fstream>
#include <iostream>
using namespace std;

istream &f(istream &in)
{
string ival;

while (in>>ival,!in.eof())
{
if(in.bad())
throw runtime_error("IO stream corrupted");
if (in.fail())
{
cerr<<"bad data,try again"<<endl;
in.clear();
in.setstate(istream::eofbit);
continue;
}
cout<<ival<<endl;
cout<<in.eof()<<endl;

}
in.clear();
return in;
}

int main()
{
ifstream readfile;
string Fname;
cout<<"Input name of file: "<<endl;
cin>>Fname;
readfile.open(Fname);
if (!readfile)
{
cerr<<"error:unable to open the file: "<<Fname<<endl;
return -1;
}
f(readfile);
//system("pause");
return 0;

}

问题如下:比如我在文件中输入的是 how are you,但是程序执行后有时只能输出how are,文件中输入1 2 3 4,程序执行后输出的是1 2 3,好像是最后的输出有问题,不知道为什么会这样,希望能有人帮忙解答一下,不胜感激!
...全文
136 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
编程小新手 2014-04-02
  • 打赏
  • 举报
回复
按你说的修改了while条件,还是不可以
赵4老师 2014-04-02
  • 打赏
  • 举报
回复
不要使用 while (条件) 更不要使用 while (组合条件) 要使用 while (1) { if (条件1) break; //... if (条件2) continue; //... if (条件3) return; //... } 因为前两种写法在语言表达意思的层面上有二义性,只有第三种才忠实反映了程序流的实际情况。 典型如: 下面两段的语义都是当文件未结束时读字符 while (!feof(f)) { a=fgetc(f); //... b=fgetc(f);//可能此时已经feof了! //... } 而这样写就没有问题: while (1) { a=fgetc(f); if (feof(f)) break; //... b=fgetc(f); if (feof(f)) break; //... } 类似的例子还可以举很多。 不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n,写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fread,fwrite,fgetc,fclose //不作以上替换,遇到\x1a仍继续读;读写的内容当字节看待 弄混了 “多一少一”问题占程序员常犯错误的10%以上! 避免“多一少一”问题的方法之一是将比如<10甚至<5的数代入程序片断,搬手指头心算验证一下程序到底应该写为 x、x-1、x+1中的哪个? <、<=、==、>、>=中的哪个?
JiMoKuangXiangQu 2014-04-02
  • 打赏
  • 举报
回复
引用 楼主 u011041370 的回复:
最近在看C++ primer,做了书上的题目,遇到了点问题,程序如下: #include <string> #include <fstream> #include <iostream> using namespace std; istream &f(istream &in) { string ival; while (in>>ival,!in.eof()) { if(in.bad()) throw runtime_error("IO stream corrupted"); if (in.fail()) { cerr<<"bad data,try again"<<endl; in.clear(); in.setstate(istream::eofbit); continue; } cout<<ival<<endl; cout<<in.eof()<<endl; } in.clear(); return in; } int main() { ifstream readfile; string Fname; cout<<"Input name of file: "<<endl; cin>>Fname; readfile.open(Fname); if (!readfile) { cerr<<"error:unable to open the file: "<<Fname<<endl; return -1; } f(readfile); //system("pause"); return 0; } 问题如下:比如我在文件中输入的是 how are you,但是程序执行后有时只能输出how are,文件中输入1 2 3 4,程序执行后输出的是1 2 3,好像是最后的输出有问题,不知道为什么会这样,希望能有人帮忙解答一下,不胜感激!
粗看了一眼,似乎没有关闭文件,对吗?
赵4老师 2014-04-02
  • 打赏
  • 举报
回复
所谓编程,说白了不就是 决定在各种复杂条件下做或不做, 以及 几乎同时做几件事时的合理顺序 吗!
编程小新手 2014-04-02
  • 打赏
  • 举报
回复
引用 10 楼 JiMoKuangXiangQu 的回复:
[quote=引用 9 楼 mujiok2003 的回复:]
stream &f(istream &in)
{
string ival;
while (in>>ival)
{  
cout<<ival<<endl;
}
return in;
}
多简单的代码,怎么搞那么复杂
确实,估计LZ是要练习下那些函数的用法吧,呵呵。[/quote] 是的,是在学习中。那样确实很简单,但是只是说程序执行没有问题,如果读取文件失败,或者输入的不是字符串,程序就会报错,但是不清楚是什么导致出错,所以要考虑全面。
JiMoKuangXiangQu 2014-04-02
  • 打赏
  • 举报
回复
引用 9 楼 mujiok2003 的回复:
stream &f(istream &in)
{
string ival;
while (in>>ival)
{  
cout<<ival<<endl;
}
return in;
}
多简单的代码,怎么搞那么复杂
确实,估计LZ是要练习下那些函数的用法吧,呵呵。
mujiok2003 2014-04-02
  • 打赏
  • 举报
回复
stream &f(istream &in)
{
string ival;
while (in>>ival)
{  
cout<<ival<<endl;
}
return in;
}
多简单的代码,怎么搞那么复杂
JiMoKuangXiangQu 2014-04-02
  • 打赏
  • 举报
回复
引用 6 楼 u011041370 的回复:
我把每次输入后和输出后的in.eof()的值输出看了下,发现读入最后一个字符串后,in.eof()便置为1,此时循环终止,导致最后一个字符串没有输出。想了下,应该是在每次输出之后再判断eof状态,并决定是否终止循环,这样就不会出现最后一个字符串还没有输出就退出循环的问题了。 修改后的程序如下:
#include <string> #include <fstream> #include <iostream> using namespace std; istream &f(istream &in) { string ival; while (1) { in>>ival; //cout<<in.eof()<<endl; if(in.bad()) throw runtime_error("IO stream corrupted"); if (in.fail()) { cerr<<"bad data,try again"<<endl; in.clear(); in.setstate(istream::eofbit); continue; } cout<<ival<<endl; if(in.eof()) break; //cout<<in.eof()<<endl; } in.clear(); return in; } int main() { ifstream readfile; string Fname; cout<<"Input name of file: "<<endl; cin>>Fname; readfile.open(Fname); if (!readfile) { cerr<<"error:unable to open the file: "<<Fname<<endl; return -1; } f(readfile); readfile.close(); return 0; } 结果:
对的,读完最后一个字符立刻就会置eof状态。 按照楼上的方法修改即可。
mujiok2003 2014-04-02
  • 打赏
  • 举报
回复
string Fname;
cout<<"Input name of file: "<<endl;
cin>>Fname;
//readfile.open(Fname);
readfile.open(Fname.c_str());
编程小新手 2014-04-02
  • 打赏
  • 举报
回复
我把每次输入后和输出后的in.eof()的值输出看了下,发现读入最后一个字符串后,in.eof()便置为1,此时循环终止,导致最后一个字符串没有输出。想了下,应该是在每次输出之后再判断eof状态,并决定是否终止循环,这样就不会出现最后一个字符串还没有输出就退出循环的问题了。
修改后的程序如下:

#include <string>
#include <fstream>
#include <iostream>
using namespace std;

istream &f(istream &in)
{
string ival;

while (1)
{ in>>ival;
//cout<<in.eof()<<endl;
if(in.bad())
throw runtime_error("IO stream corrupted");
if (in.fail())
{
cerr<<"bad data,try again"<<endl;
in.clear();
in.setstate(istream::eofbit);
continue;
}
cout<<ival<<endl;
if(in.eof()) break;
//cout<<in.eof()<<endl;

}
in.clear();
return in;
}

int main()
{
ifstream readfile;
string Fname;
cout<<"Input name of file: "<<endl;
cin>>Fname;
readfile.open(Fname);
if (!readfile)
{
cerr<<"error:unable to open the file: "<<Fname<<endl;
return -1;
}
f(readfile);
readfile.close();
return 0;

}
结果:
JiMoKuangXiangQu 2014-04-02
  • 打赏
  • 举报
回复
引用 4 楼 u011041370 的回复:
按你说的修改了while条件,还是不可以
while (in>>ival,!in.eof())
修改为:
while (in>>ival/*,!in.eof()*/)
即可。 代码 while (in>>ival,!in.eof()) 的循环条件是1个逗号表达式,结果取最右边的值。 当in>>ival读完最后一个数的时候,eof标记已经被设置,所以最后一个字符串总打印不出来。
turing-complete 2014-04-01
  • 打赏
  • 举报
回复
友情提示,谨防上当。 如果,有人进来说:“摒弃std::cout和std::cin,改用printf和scanf”。请忽略此回复。 如果有人说:
“计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……

对学习编程者的忠告:
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步对应汇编一行!”
那么说明,他不懂这个问题如何,却在白占楼层和篇幅,您可以直接开骂。

64,648

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧