1.5联合体和IO
1.5.1联合体概念
联合体(共用体)
不同类型的变量共同占用一段内存(相互覆盖),联合变量任何时刻只有一个成员存在,节省内存
联合体变量的大小=最大的成员所占的字节数
union MyValue{ int x; int y; double z; }; void main(){ union MyValue d1; d1.x = 90; d1.y = 100; d1.z = 23.8; //最后一次赋值有效 printf("%d,%d,%lf\n",d1.x,d1.y,d1.z); system("pause");
} |
1.5.2枚举概念
枚举值默认从 0 开始,往后逐个加 1(递增)
枚举的值,必须是大括号中的值
enum Day { Monday = 0,//这里也可以设置其他整数 Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }; |
1.5.3 IO操作
常用函数
执行字符/文本行/二进制I/O的函数
数据类型 | 输入 | 输出 | 描述 |
字符 | getchar | putchar | 读取(写入)单个字符 |
文本行 | gets scanf | Puts printf | 文本行未格式化的输入(输出) 格式化的输入(输出) |
二进制数据 | fread | fwrite | 读取(写入)二进制数据 |
1. 只用于stdin或stdout
2. 随作为参数的流使用
3. 使用内存中的字符串而不是流
常用读写模式:
"r"(只读)
为输入打开一个文本文件,不存在则失败
"w"(只写)
为输出打开一个文本文件,不存在则新建,存在则删除后再新建
"a"(追加)
向文本文件尾部增加数据,不存在则创建,存在则追加
'rb"(只读)
为输入打开一个二进制文件,不存在则失败
"wb"(只写)
为输入打开一个二进制文件,不存在则新建,存在则删除后新建
"ab"(追加)
向二进制文件尾部增加数据,不存在则创建,存在则追加
"r+"(读写)
为读写打开一个文本文件,不存在则失败
"w+" (读写)
为读写建立一个新的文本文件,不存在则新建,存在则删除后新建
"a+"(读写)
为读写打开一个文本文件,不存在则创建,存在则追加
"rb+"(读写)
为读写打开一个二进制文件,不存在则失败
"wb+"(读写)
为读写建立一个新的二进制文件,不存在则新建,存在则删除后新建
"ab+"(读写)
为读写打开一个二进制文件,不存在则创建,存在则追加
函数名: fopen
功 能: 打开一个流,失败返回NULL,FILE并不是指文件,而是一个与文件相关联的流。
用 法: FILE *fopen(char *filename, char *type);
函数名: fclose
功 能: 关闭一个流
用 法: int fclose(FILE *stream);
函数名: fgets
功 能: 从流中读取一字符串
用 法: char *fgets(char *string, int n, FILE *stream);
参数:
string: 字符型指针,指向存储读入数据的缓冲区的地址。
n: 从流中读入n-1个字符
stream : 指向读取的流。
返回值:
1. 当n<=0 时返回NULL,即空指针。
2. 当n=1 时,返回空串"".
3. 如果读入成功,则返回缓冲区的地址。
4. 如果读入错误或遇到文件结尾(EOF),则返回NULL.
函数名: fputs
功 能: 送一个字符到一个流中
用 法: int fputs(char *string, FILE *stream);
参数:string为将要写入的字符串,stream为文件流指针。
返回值:成功返回非负数,失败返回EOF。
代码示例:
在C语言中,文件路径会被写作字符串形式,但是由于C语言的字符串规则中,\字符是转义字符的引导,所以’\’要写成’\\’
读取字符串
#define _CRT_SECURE_NO_WARNINGS #include <stdlib.h> #include <stdio.h> #include "string.h" void main() { char* path = "E:\\files\\friends.txt"; FILE *fp = fopen(path, "r"); if (fp == NULL) { printf("文件读取失败"); getchar(); return; }
char re[50]; while (fgets(re,50,fp)) { printf("%s", re); } fclose(fp); getchar(); } |
写入字符串
void main() { char* path = "E:\\files\\friends.txt"; FILE *fp = fopen(path, "w"); if (fp == NULL) { printf("文件写入失败"); getchar(); return; }
char * wr = "无敌是多么寂寞!"; fputs(wr, fp); fclose(fp); getchar(); } |
计算机的文件存储在物理上都是二进制,文本文件和二进制之分,其实是一个逻辑之分,C读写文本文件与二进制文件的差别仅仅体现在回车换行符,写文本时,每遇到一个'\n',会将其转换成'\r\n'(回车换行),读文本时,每遇到一个'\r\n',会将其转换成'\n'
函数名: fread
功 能: 从一个流中读数据fread()函数每次从stream中最多读取nitems个单元,每个单元大小为size个字节,将读取的数据放到buffer;文件流的位置指针后移size * nitems字节。
用 法: int fread(void *ptr, int size, int nitems, FILE *stream);
参数: ptr为接收数据的地址,size为一个单元的大小,nitems为单元个数,stream为文件流。
返回值:返回实际读取的单元个数。如果小于nitems,则可能文件结束或读取出错;如果size或nitems为0,则返回0。
函数名: fwrite
功 能: 写内容到流中
用 法: int fwrite(void *ptr, int size, int nitems, FILE *stream);
复制文件:
void main() { char* path = "E:\\files\\liuyan.png"; char* path_new = "E:\\files\\liuyan_new.png"; FILE *fp = fopen(path, "rb"); FILE *fp_new = fopen(path_new, "wb"); int buf[50]; int len = 0; while ((len = fread(buf,sizeof(int),50,fp)) != 0) { fwrite(buf, sizeof(int), len, fp_new); }
fclose(fp); fclose(fp_new);
getchar(); } |
函数名: fseek
功 能: 重定位流上的文件指针
用 法: int fseek(FILE *stream, long offset, int fromwhere);
参数: 操作的流,偏移量,移动到哪里
函数名: ftell
功 能: 返回当前文件指针相对于文件开头的位移量
用 法: long ftell(FILE *stream);
获取文件大小:
void main() { char* path = "E:\\files\\liuyan.png"; FILE *fp = fopen(path, "rb"); fseek(fp,0,SEEK_END); long size = ftell(fp); printf("%d", size); fclose(fp); getchar(); } |