依然还是从一个程序说起:将一个文件复制到另一个文件
C语言来实现:
#include<stdio.h>
#include<stdlib.h>
int main(int argc,char *argv[]){
FILE *in,*out;
int ch;//gets()函数的返回值是int型的
if(argc!=3){//如果参数数量不是三个 就输出提示语句
fprintf(stderr,"输入形式:copyFile 源文件名 目标文件名 \n");
exit(0);
}
//如果输入流文件没有正常打开 就向标准错误流stderr发送一条消息
if((in=fopen(argv[1],"rb"))==NULL){//第一个参数是文件名类型的字符串 在调用函数实际是传入字符串的地址 argv[1]就是源文件名的地址 所以不用加引号
fprintf(stderr,"源文件%s无法正常打开!\n",argv[1]);
exit(0);
}
//如果输出流文件没有正常打开
if((out=fopen(argv[2],"wb"))==NULL){
fprintf(stderr,"目标文件%s无法正常打开!\n",argv[2]);
fclose(in);//in已经打开 必须在程序关闭之前关掉文件
exit(0);
}
//二者都正常打开
while((ch=getc(in))!=EOF){ //getc()函数依次从输入流(stdin)读取一个字符
if(putc(ch,out)==EOF) break;//putc()函数把这个字符写入到输出流(stdout) 在这里写入字符是 ch 输出流是out
}
if(ferror(in)){
printf("读取%s文件失败\n",argv[1]);
return 0;
}
if(ferror(out)){
printf("读取%s文件失败\n",argv[2]);
return 0;
}
printf("成功复制一个文件!\n");
fclose(in);
fclose(out);
return 0;
}
- in和out是我们声明的两个文件指针,她们的类型都是FILE*,分别作为两个I/O流对象来使用。
- argc和argv[]:在程序中,main函数有两个参数,整型变量argc和字符指针数组argv[].。argc的含义是程序的参数数量,包含本身。所以在程序里首先判断参数是不是三个 如果不是三个的话,就按照所给格式重新输入。argv[]的每个指针指向命令行的一个字符串,是字符指针数组,所以argv[0]指向字符串"copyFile.exe",argv[1]指向字符串sourceFile,argv[2]指向字符串destFile。
- getc()函数依次从输入流(stdin)读取一个字符,putc()函数把这个字符写入到输出流(stdout) 在这里写入字符是 ch 输出流是out
- 当getc()遇到文件结束标志的时候,函数的返回值是EOF。EOF是一个宏,在stdio.h中定义,值为一个负整数,通常是-1.EOF事实上有两个含义,一个是读到文件结束标志,还有一个是在对文件进行操作的时候出现了错误。为了排除第二种情况,在程序里对文件进行ferror操作。
注意细节:getc()的返回值是int类型,所以我们在声明ch是是整形而不是char型。
C++来实现:
#include<iostream>//标准输入输出流的类
#include<fstream>//文件流的类 关于类的概念 后续笔记中会有
using namespace std;
int main(){
ifstream in;//创建一个文件输入流对象
in.open("test.txt");//调用这个类里面的open()函数 如果调用失败的话 返回0
if(!in){
cerr<<"打开文件失败"<<endl; //向标准错误流里输入提示语句 在C里是stderr 在C++里是cerr 不能用cout cout是标准输出流
return 0;
}
char x;
while(in>>x){//文件流 向x流一个字符
cout<<x;//向屏幕输出
}
cout<<endl;
in.close();
return 0;
}
#include<iostream>//标准输入输出流的类
#include<fstream>//文件流的类 关于类的概念 后续笔记中会有
using namespace std;
int main(){
ofstream out;//创建一个文件输出流对象
out.open("test.txt");//调用这个类里面的open()函数 如果调用失败的话 返回0
if(!out){
cerr<<"打开文件失败"<<endl; //向标准错误流里输入提示语句 在C里是stderr 在C++里是cerr 不能用cout cout是标准输出流
return 0;
}
for(int i=0;i<10;i++){
out<<i;//向输出流中插入i
}
out<<endl;//结束输出 结果就是 会向out打开的文件里 输出0~9
out.close();
return 0;
}
在这两个例子中出现了 ifstream in; ofstream out;但是不是只有这一种方法 还可以使用别的方法来声明对象 例如利用构造函数 重载等,后续会有笔记。