MyGitHub
输入方式
所有方式都是通过命令行传递,即在第四次的基础上新增:
带等号的等式
需要在scan中新增对等号的判断,即遇见等号跳出循环即可
if (input[i] == '=')
{
break;
}
自定义文件名文件流输入输出(FILE*stream)
判断当X:argv[1]=="-f"时,则Y为输入文件路径,z为输出文件路径(默认路径存在),通过资料查阅得知,常用的文件输入输出方式有:
-
fstream
fstream //输入文件流
ofstream //输出文件流
需要头文件:fstream
由于教程太过详细,便不在这里一一唠叨,就写写我学到的。-
文件打开方式
1. ifstream(filename); //只读,此时默认打开方式为ios::in,若文件不存在则创建文件;注意文件路径斜杠双写,例:"E://in.txt")
2. 使用成员函数open
fstream f;
f.open(filename,ios::out||ios::in); //读写的方式打开文件
以上两种打开方式的区别主要在于:如果你想用一个句柄打开多个文件或不马上指定文件路径(如本次作业情况),可以选择f.open(); -
检查文件是否成功打开
可以用一个bool函数判断
bool F{if(f)...} -
读写操作
f>>x; //读取数据
f<<x; //写入数据 -
关闭文件
f.close(); -
根据以上所学知识,一个简单的测试代码
void main()
{
int i;
fstream f,fs;
string filename_out;
cin >> filename_out; //输出文件名自定义
f.open("D://test.txt",ios::in); //打开输入文件
fs.open(filename_out.c_str(),ios::out); //创建输出文件
while (!f.eof()) //处理至文件结束
{
f >> i;
fs << i;
}f.close(); //关闭文件
fs.close();
}
-
-
freopen
函数声明:FILE *freopen( const char *path, const char *mode, FILE *stream );
需要头文件:stdio.h-
文件打开方式:
FILE* stream;
freopen("in.txt","r",stdin); //输入重定向,此时输入的数据从in.txt文件读取,并且in.txt文件在工程//Debug文件夹下和.exe处于同一个位置。
//"r"是文件打开模式,*mode对应下 r-只读,w-写
//stdin标准输入流,默认键盘;stdout标准输出流,默认屏幕 -
输入输出
保持原函数不变 -
关闭文件
fclose(stdin);
fclose(stdout); -
测试代码
int main() { int a, b; char s[20]; void cal(int c, int d); FILE *stream; cin >> s; freopen_s(&stream,s,"r",stdin); freopen_s(&stream,"output.txt", "w", stdout); while (cin >> a >> b) cout << a + b << endl; fclose(stdin);//关闭文件 fclose(stdout);//关闭文件 return 0; }
-
-
方法比较:
以上两种方式目前在我看来似乎并没有很大的区别,但是freopen
的一大优势是对原有的代码完全不用修改~~十分方便,只要加上几行重定向语句就好了!!
所以我选用freopen
,但是在vs_2015实测中,如果按照大多数教程的重定向语句写成这样freopen(s,"r",stdin);
,vs会提示改成freopen_s
,然后会告诉你不接受3个参数...一开始改了很久,然后看了一下vs提供的解决方案,总算是明白了freopen_s
的函数声明为 freopen_s(FILE**_stream,char const_FileName,char const_Mode,FILE* _OldStream),说白了应写成 freopen_s(&stream,filename,"r",stdin); 格式即可。
值得注意的是,在fstream中,输入文件不存在可自动创建,而用freopen需要指定已存在的文件。 -
自定义文件名:
本题文件路径由用户端的参数控制由于函数freopen
的filename只接受char类型的参数,所以我选择用string接受用户输入,然后借用c_str()函数转换FILE*stream; string filename; cin >> filename; freopen_s(&stream,filename.c_str(),"r",stdin);
-
我的相关代码:
if (argv[1] == "-f") { string filename_in, filename_out; filename_in = argv[2]; filename_out = argv[3]; FILE* stream; freopen_s(&stream, filename_in.c_str(), "r", stdin); //重定向 freopen_s(&stream, filename_out.c_str(), "w", stdout); while (cin >> s1) //输入到文件结束 { calcu(s1); //调用函数队式子进行计算并输出 } fclose(stdin); //关闭文件 fclose(stdout); }
命令行输入:
文件输入:
输出文件:
- 所有输出代码都在printf函数内:
之前确实偷懒了一下下部分输出直接在main函数进行,于是printf函数变得鸡肋~于是在printf.cpp
新建了<报错><结果输出><表达式输出>函数
描述框架图
注:以下所有调用皆在main.cpp进行,箭头只是判断关系。
参考资料:
更新16/5/23
- 将freopen换成更高效率的fstream,并分别在scan和printf中执行输入输出文件流。输出文件流用到了“ios;;app”。
- 合并calculation和result类,减少函数调用次数,提高效率。
- 删去多余的代码注释和旧版本。
- 各个类函数之间的调用仍然过于冗杂,还在继续优化修改。