fopen fwrite fread函数的介绍

1.简介

/*The fopen() function opens the file whose name is the string pointed to 
by pathname and associates a stream with it.*/
/*fopen会打开pathname指向的文件,并会将其和一个流相关联(流是什么?这个挺抽象的,
简单来说就是可以传送数据的通道。),然后会将文件结构体(关于文件结构体要存放什么,
具体细节,可以看看有关文件系统的博客)的指针返回。*/
FILE *fopen(const char *pathname, const char *mode);

/*The function fread() reads nmemb items of data, each size bytes long, 
from the stream pointed to by stream, storing them at the location given by ptr.*/
/*fread会从文件指针stream指向的文件,读取nmemb个size大小的内容,放到ptr所指向的缓存中。
(顺便提一下,这里也是void*这个万能指针的常规用法) */
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

/* The function fwrite() writes nmemb items of data, each size bytes long, 
to the stream pointed to by stream, obtaining  them from the location given by ptr.*/
/*fwrite会从ptr所指向的数据中,写nmemb个size大小的内容到stream中*/
size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);

 /* On success, fread() and fwrite() return the number of items read or written.  
 This number equals the number of bytes trans‐ferred only when size is 1.  
 If an error occurs, or the end of the file is reached, 
 the return value is a short item  count (or zero).*/
 /* fread()  does  not distinguish between end-of-file and error, 
 and callers must use feof(3) and ferror(3) to determine which occurred.*/
 /*fread和fwrite如果执行成果会返回写入的items的个数,也即nmemb。如果发生错误或已经到达文件结尾,会返回成果读取的items个数(小于nmemb)或者返回0,fread不会区分错误和文件结束,必须自己使用feof和ferror来判断(可以之前看看关于EOF介绍的文章)*/
打开方式 解释
r Open text file for reading. The stream is positioned at the beginning of the file.
r+ Open for reading and writing. The stream is positioned at the beginning of the file.
w Truncate file to zero length or create text file for writing. The stream is positioned at the beginning of the file.
w+ Open for reading and writing. The file is created if it does not exist, otherwise it is truncated. The stream is positioned at the beginning of the file.
a Open for appending (writing at end of file). The file is created if it does not exist. The stream is positioned atthe end of the file.
a+ Open for reading and appending (writing at end of file). The file is created if it does not exist. The initialfile position for reading is at the beginning of the file, but output is always appended to the end of the file.
b The mode string can also include the letter ‘b’ either as a last character or as a character between the characters in any of the two-character strings described above. This is strictly for compatibility with C89 and has no effect; the ‘b’ is ignored on all POSIX conforming systems, including Linux. (Other systems may treat text files and binary files differ‐ently, and adding the ‘b’ may be a good idea if you do I/O to a binary file and expect that your program may be ported to non-UNIX environments.)

简单总结一下,r是以只读方式打开,w以只写方式打开(不存在时会新建,存在时会抹除文件已有内容),r+,w+以读写方式打开文件。这几种方式打开后文件指针都在文件开头处。
a 会以追加的方式打开(文件不存在会新建,文件存在不会覆盖),a+读写方式打开(读文件时文件初始指针在开头,写时候还是追加)。
b 以二进制方式打开,在所有支持POSIX的系统上添加b和不添加b没有任何影响,但是对于此外的其它系统有可能会不同,因此最好使用b模式来操作IO,方便程序移植。
这里以Linux(支持POSIX)和Windows(微软生成支持部分POSIX)系统介绍一下b这种模式。先说明两个规定:
1.二进制方式打开文件进行读写时不会进行额外的解析,整个流是什么样就是什么样。
2.文本方式打开文件进行写入时,会将每一个0x0a前面加一个0x0d变为Window下的换行符CRLF(\r\n),而Linux下不会进行此操作。文本方式打开文件进行读取时,Windows下会将CRLF解析为换行,同时遇到CTRLZ(0x1A)时认为文件已经结束。

因此,分以下情况讨论:
1.文本方式写入,文本方式打开。
此时在Windows下会将\n变为\r\n进行保存,而且会将CTRLZ作为文件结束。在Linux下无影响。
2.文本方式写入,二进制方式打开。
二进制读取时原样读出,会把\r\n都读出来。Linux下无影响。
3.二进制方式写入,文本文件方式打开
Windows存在将CTRLZ解析为文件结束风险,Linux下无影响。
4.二进制方式写入,二进制方式打开
无影响。
此外Linux下以文本方式打开方式操作的IO流,在Window下下载文件可能会变大。
综上,为了安全起见,在不是完全支持POSIX的系统上编程时建议每次进行IO操作时都加上b!!

2.使用

1.文本方式写入,文本方式读取。

void encodeByZH_CN() {
	FILE* fp;
	if ((fp = fopen(FILENAME, "w+")) == NULL) {
		cout << "文件打开失败" << endl;
		return;
	}
	//以文本方式写入
	char name[] = "张张张";
	int writecount = fwrite(name, sizeof(name), 1, fp);
	cout << writecount << endl;
	char temp[7] = {0};
	fseek(fp, 0, SEEK_SET);
	//以文本方式读出 存取和读出都是以文本 控制台也是GBK编码 因此可以正常显示
	int readCount = fread(temp, sizeof(temp), 1, fp);
	cout <<readCount << endl;
	cout << temp << endl;
}

fopen fwrite fread函数的介绍_第1张图片
成功打印。
fopen fwrite fread函数的介绍_第2张图片

2.文本方式写入,二进制方式打开

void encodeByText() {
	FILE* fp;
	if ((fp = fopen(FILENAME, "w+")) == NULL) {
		cout << "文件打开失败" << endl;
		return;
	}
	//以文本方式写入
	char name[] = "tttttt";
	int writecount = fwrite(name, sizeof(name), 1, fp);
	cout << writecount << endl;
	fclose(fp);
	if ((fp = fopen(FILENAME, "r+b")) == NULL) {
		cout << "文件打开失败" << endl;
		return;
	}
	char temp[7] = { 0 };
	fseek(fp, 0, SEEK_SET);
	//以文本方式读出 存取和读出都是以文本 控制台也是GBK编码 因此可以正常显示
	int readCount = fread(temp, sizeof(temp), 1, fp);
	cout << readCount << endl;
	cout << temp << endl;
	fclose(fp);
}

fopen fwrite fread函数的介绍_第3张图片
fopen fwrite fread函数的介绍_第4张图片
fopen fwrite fread函数的介绍_第5张图片

3.二进制方式写入,文本方式打开
fopen fwrite fread函数的介绍_第6张图片
这里对应前面说的Windows下文本方式会认为0x1a代表文件结束,因此读出tt。
fopen fwrite fread函数的介绍_第7张图片
但是记事本里面确实换行了????
fopen fwrite fread函数的介绍_第8张图片
4.二进制写,二进制读,很简单不再演示。

你可能感兴趣的:(c++,c语言,算法)