注掉第二个函数,只用第一个,无限读入
注掉第一个函数,只用第二个,vector.size()==0
谢谢HJIN版,我现在基本明白eof()判断什么了
还有一个问题,我在开贴的时候提出的:这种函数为什么要写成stream& func(stream$)的形式,二楼aipb2007版给我解释的是因为便于连用我有些不太理解。。
按我们一般理解函数的方式,引用形参传递是非复制传递,我们可以在函数中直接处理传递进来的流,而不是复制这个流(流本身的特性也决定它不能复制,这点恰好成立)。只是这里:函数得到实参的引用然后又返回实参的引用的意义怎么来体现呢?是为了出现可能的比如stream& sample=func(stream&)的用法吗?
还是像aipb2007版所说的那种cin>>a>>b式的连用?
如果是后者,那么前面那个process_input函数,您可以举个例子给我看一下这种用法吗?
yes, it is the chain action which demands the function prototype. This is very similar to
// assignment:
a = b = 2;
or insertion and extraction:
cout<<a<<b<<endl;
cin>>a>>b;
class A
{
friend std::istream& operator>> (std::istream& is, A& obj);
public:
A(int i_=0) : i(i_) { }
private:
int a;
};
std::istream& operator>> (std::istream& is, A& obj)
{
int i;
is>>i;
obj.a=i;
return is;
}
A objA;
double d;
cin>>objA>>d;
嗯,这个现在也基本明白,谢谢HJin版,不过又有新问题
关于ofstream::app,请看我下面的代码
我就是实现了一个简单的txt文件copy,通过main形参指定读和写的文件名(无须扩展名)
打开文件的模式在我用红色标明那行里指定,按理说如果我多次对同一文件做写入操作,那个文件里应该有多个读入文件的副本,可事实是:显式指定app和未指定是一样的,就好像显式地指定了out
我的环境是vc60,请你在vc80下试试
还有一个问题:我在这个程序里使用vector保存,方法是申请了全局的vector,如果我想在main里申请这个vector,怎么把它传到process_input里让它能动态增长为好?用svec_it& svec?这种引用方式?或者如果是你,你会怎么处理,请传授点经验~谢谢!
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
using namespace std;
typedef std::vector<string>::const_iterator svec_it;
vector<string> svec;
ofstream& output_file(ofstream& stm,string& filename,svec_it beg,svec_it end)
{
stm.close();//奇怪,第一次一定得先关掉清理一次流,再重新打开才行。
stm.clear();
stm.open(filename.c_str(),ofstream::app);//这里奇怪
if (!stm)
{
cout<<"文件打开失败"<<endl;
stm.setstate(ofstream::badbit);
return stm;
}
for (svec_it iter=beg;iter!=end;++iter)
{
stm<<*iter<<endl;
}
stm<<flush;
cout<<"文件存储完成"<<endl;
stm.close();
stm.clear();
return stm;
}
istream &process_input(istream& is)//本函数作用:读入流,打印出来
{
if (!is)
{
cout<<"打开指定文件失败"<<endl;
is.setstate(istream::badbit);
// is.clear();
// is.ignore();
return is;
}
string str;
int flag=1;
cout<<"正在进行读入操作,请稍候..."<<endl;
while (getline(is,str),!is.eof())
{
if (is.bad())
{
throw runtime_error("该文件已经损坏,不可读取!");
cout<<"系统IO错误,无法读取"<<endl;
}
if (is.fail())
{
cerr<<"第"<<flag<<"处读取错误,跳过"<<endl;
is.clear();
is.ignore();
++flag;
continue;
}
svec.push_back(str);
++flag;
}
/* cout<<"已经读入文件,现在打出来"<<endl;
for (svec_it it=svec.begin();it!=svec.end();++it)
{
cout<<*it<<endl;
}
cout<<endl;
*/
return is;
}
int main(int argc,char** argv)
{
while (argc!=3)
{
cout<<"参数数目不符"<<endl;
cout<<"按q退出"<<endl;
char a;
cin>>a;
if ('q'==a)
{
return EXIT_FAILURE;
}
else
{
continue;
}
}
//前面写完了参数错误时候的情况,下面写正确处理
string str_input(".txt");
str_input=argv[1]+str_input;
ifstream input(str_input.c_str());
process_input(input);
if (input.bad())
{
cout<<"调用文件处理函数读入操作失败,请检查输入文件名"<<endl;
input.clear();
input.ignore();
return EXIT_FAILURE;
}
else
{
cout<<"已经处理完读入文件,现在将文件写入预定的文件中...;"<<endl;
}
string out_file(".txt");
out_file=argv[2]+out_file;
ofstream output(out_file.c_str());
//output.close();这个文件输出流有点怪,如果这里使用时候不进行关掉清理流的操作,在调用函数里就得补上这一步
//output.clear();
output_file(output,out_file,svec.begin(),svec.end());
if (output.bad())
{
cout<<"调用文件处理函数写入操作失败,请检查该文件是否设置了只读或其它设备原因"<<endl;
output.close();
output.clear();
return EXIT_FAILURE;
}
else
{
return EXIT_SUCCESS;
}
}