c语言fread()fwrite()fseek()

好久没用c语言的这部分的东西了,今天看到一个练习是:将notepad.exe读取到内存中,然后将这片内存中的内容写入到一个空二进制文件中,看新生成的二进制文件是否可执行

不做这个练习,凭自己大一瞎搞过来的经验也知道,是可以执行的,可是实际做的时候居然不行,是因为对C语言文件操作部分不熟,被坑了好久。。。唉

涉及到几个函数的使用:fclose()、fopen()、fread()、fwrite()、fseek()

fopen()

fopen()是文件打开函数,返回可以访问文件内容的文件指针

使用格式:

fopen(“filename”,”mode”);

filename为要打开的路径
mode为:w(写)、r(读)、a(追加)以及配合他们使用的b(二进制方式)
不使用带b后缀的打开模式时,使用文本模式

fclose()

fclose()用于断开系统与打开的文件的指针的之间的联系,可以使得还在缓冲区中的数据保存到文件中
使用格式: fclose(FILE *fp)

fread()

从文件流中读数据,最多读取count个项,每个项size个字节,如果调用成功返回实际读取到的项个数(小于或等于count),如果不成功或读到文件末尾返回0

原型:

size_t fread ( void _buffer, size_t size, size_t count, FILE_ stream) ;

参数:

参 数

buffer 用于接收数据的内存地址

size 要读的每个数据项的字节数,单位是字节

count 要读count个数据项,每个数据项size个字节.

stream 输入流

返回值 返回真实读取的项数,若大于count则意味着产生了错误。另外,产生错误后,文件位置指示器是无法确定的。若其他stream或buffer为空指针,或在unicode模式中写入的字节数为奇数,此函数设置errno为EINVAL以及返回0.

fwrite()

向指定的文件中写入若干数据块,如成功执行则返回实际写入的数据块数目。该函数以二进制形式对文件进行操作,不局限于文本文件

原型:

size_t fwrite(const void _buffer, size_t size, size_t count, FILE_ stream);

参数:

(1)buffer:是一个指针,对fwrite来说,是要获取数据的地址;

(2)size:要写入内容的单字节数;

(3)count:要进行写入size字节的数据项的个数;

(4)stream:目标文件指针;

(5)返回实际写入的数据项个数count。

fseek()

执行成功的话,stream将指向以fromwhere为基准,偏移offset(指针偏移量)个字节的位置,函数返回0。如果执行失败(比如offset超过文件自身大小),则不改变stream指向的位置,函数返回一个非0值。

原型:

int fseek(FILE *stream, long offset, int fromwhere);

函数设置文件指针stream的位置。如果执行成功,stream将指向以fromwhere(偏移起始位置:文件头0(SEEK_SET),当前位置1(SEEK_CUR),文件尾2(SEEK_END))为基准,偏移offset(指针偏移量)个字节的位置。如果执行失败(比如offset超过文件自身大小),则不改变stream指向的位置。

下面是我的实现代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>

#include<stdlib.h>

int main(int argc, char *argv[])

{

int length;

FILE * fp = fopen(argv[1], "rb"); //可读模式打开文件

fseek(fp, 0, SEEK_END); //将文件指针弄到文件位

length = ftell(fp); //将文件的长度返回给length

fseek(fp, 0, SEEK_SET);

char * text = (char *) malloc(length*sizeof(char));

fread(text, sizeof(char), length, fp);

fseek(fp, 0, SEEK_SET);

FILE *op = fopen(argv[2], "wb");

fwrite(text, sizeof(char), length,op); //将加载到内存中的文件写入到一个二进制文件中

fclose(fp);

fclose(op);

free(text);

}