《C++快速入门》学习笔记
b站指路:鱼C-小甲鱼
进度:P4
编程任务:编写一个文件复制程序
C语言:
思路:
1、 首先确保输入参数个数正确,否则抛出错误
2、 然后用if ((in = fopen(argv[1], "rb")) == NULL)这个语句实现了用二进制可读打开源文件,并且将地址传给指针in,然后还判断了是否打开成功这三个功能。如果成功就返回指针,否则抛出错误。
3、 再用if ((out = fopen(argv[2], "wb")) == NULL)这个语句实现了和上面差不多的功能(注意是可写形式打开),值得注意的是这一块if语句当中加入了fclose(in),是为了防止【源文件能打开但是目标文件无法打开】的情况,在读取下一句退出之前关闭了输入流文件,确保了文件的安全性。这个地方容易出隐藏的bug。
4、 在确保以上无误的情况下,用while ((ch = getc(in)) != EOF)语句来不断读取in当中的字符,如果遇到文件尾,那么跳出循环。里面嵌套的if (putc(ch, out) == EOF)语句也同样实现了把ch写入输出流,同时判断是否遇到文件尾的两个功能。这一块是实现文件复制的核心。
5、 最后用ferror()来判断是否是文件读取/写入错误导致返回EOF提前结束程序(因为返回EOF的情况有文件尾和读写错误两种)
6、 最后fclose()关闭文件
【关于传入参数】
argc是整型变量,是程序的参数数量,包含本身
argv[]是字符指针数组,每个指针指向命令行的一个字符串
argv[0]指向字符串“copyFile.exe”
argv[1]指向字符串sourceFile
arge[2]指向字符串destFile
【关于文件指针】
in和out是我们声明的两个文件指针,分别作为两个I/O流对象使用(文件是存储在磁盘上的,我们要使用的时候就需要将其拿到内存中,故要进行内存的分配,故使用FILE*的指针来操作)
【关于getc()】
Each of these functions returns the character read. To indicate an read error or end-of-file condition, getc and getchar return EOF.
注意:
getc()返回值是int类型,所以我们声明时是int ch,而不是char ch
C++:
思路和上面C语言相同:
1、ifstream in("test.txt")在声明的过程当中就调用了构造函数,如果打开失败,那么会返回一个0,故下面一句if (!in)用来判断打开失败的情况。
2、接着用一个字符x来从in当中接收字符,再流出,最后关闭文件
Ifstream其实是一个文件输入流的类,我们声明了它的对象in,那么in就拥有了这个类的属性。
C++相比C语言的优势就在于声明类的对象的时候,这个对象就有了类的属性,代码更加简洁清晰,封装性很强。
在构造的时候可以加入第二个参数表示打开模式,
常见的几种打开模式:
Ios::in—打开一个可读取文件
Ios::out—打开一个可写入文件
Ios::binary—以二进制形式打开
Ios::app—写入的数据追加到文件末尾
Ios::trunk—删除文件原来已存在的内容
Ios::nocreate—如果要打开的文件不存在,那么无法执行
Ios::noreplece—如果要打开的文件已存在,则返回错误
同时应用多种打开模式:
可以用|来连接,因为它们的本质是枚举类型,转化成二进制后对应着1,10,100,1000等等,占据了不同的位,那么进行|的运算时,1|100的运算结果就是101,这样就可以通过读取每一位来判断分别是哪几种打开模式
写在后面:
关于文件的修改等内容以后还需要更多注意,尤其是main函数当中传入参数这一点,因为归根到底这一部分我还没有办法跑起来x
C语言的版本在VS2019当中会无法运行,原因就是fopen()被认定为不够安全,而C++版本的代码是我自己参考小甲鱼给的几个示例摸索着写的,所以没能实现“输入文件名进行操作”这一点,代码不够灵活。在仿照上面C语言的传参方式的时候,能通过编译,但是程序没给我输入的机会em
C++在对于重复代码的使用这一块上面让人感觉到比C语言的效率更高一些。
最后还有一点就是,在读取不确定长度的内容时,一个思路就是用循环读取,在尾部跳出。
IT双侠的咕咕咕日常
内容:咸哥
排版:咸哥
特别鸣谢:小甲鱼