共用体和联合体:
union test {
char ch;
short sh;
int var;
};
联合体,内部所有成员变量地址一致。等同于整个联合体的地址。
联合体的大小,是内部成员变量中,最大的那个成员变量的大小。(对齐)
修改其中任意一个成员变量的值,其他成员变量会随之修改。
示例
typedef union test
{
char ch;
short sh;
int a;
} test_t;
int main(void)
{
test_t obj;
obj.a = 0x87654321;
printf("&obj =%p\n", &obj);
printf("&obj.ch =%p\n", &obj.ch);
printf("&obj.sh =%p\n", &obj.sh);
printf("&obj.a =%p\n", &obj.a);
printf("sizeof(test_t) = %u\n", sizeof(test_t));
printf("a = 0x%x\n", obj.a);
printf("sh = 0x%x\n", obj.sh);
printf("ch = 0x%x\n", obj.ch);
system("pause");
return EXIT_SUCCESS;
}
枚 举:
enum color { 枚举常量 };
enum color { red, green, blue, black, pink, yellow };
枚举常量: 是整型常量。不能是浮点数。可以是负值。 默认初值从 0 开始,后续常量较前一个常量 +1.
可以给任意一个常量赋任意初值。后续常量较前一个常量 +1
示例
enum color {red, green = 5, blue, black =10, pink, yellow};
int main(void)
{
int flg = 2;
if (flg == blue)
{
printf("blue is 2");
}
else
{
printf("blue is not 2,blue is %d\n",blue);
}
printf("pink is %d\n",pink);
system("pause");
return EXIT_SUCCESS;
}
读写文件与printf、scanf关联
printf
scanf
perror
系统文件:
标准输入 -- stdin -- 0
标准输出 -- stdout -- 1
标准错误 -- stderr -- 2
应用程序启动时,自动被打开,程序执行结束时,自动被关闭。 ---- 隐式回收。
1s = 1000ms
1ms = 1000us
1us == 1000ns
文件指针和普通指针区别:
FILE *fp = NULL
借助文件操作函数来改变 fp 为空、野指针的状况。 fopen()
操作文件, 使用文件读写函数来完成。 fputc、fgetc、fputs、fgets、fread、fwrite

文件分类:
设备文件:
屏幕、键盘、磁盘、网卡、声卡、显卡、扬声器...
磁盘文件:
文本文件: ASCII
二进制文件: 0101 二进制编码
文件操作一般步骤:
1. 打开文件 fopen() --》 FILE *fp;
2. 读写文件 fputc、fgetc、fputs、fgets、fread、fwrite
3. 关闭文件 fclose()
打开、关闭文件函数:
FILE * fopen(const char * filename, const char * mode);
参1:待打开文件的文件名(访问路径)
参2:文件打开权限:
"r": 只读方式打开文件, 文件不存在,报错。存在,以只读方式打开。
"w": 只写方式打开文件, 文件不存在,创建一个空文件。文件如果存在,清空并打开。
"w+":读、写方式打开文件,文件不存在,创建一个空文件。文件如果存在,清空并打开。
"r+":读、写方式打开文件, 文件不存在,报错。存在,以读写方式打开。
"a": 以追加的方式打开文件。
"b": 操作的文件是一个二进制文件(Windows)
返回值:成功:返回打开文件的文件指针
失败:NULL
int fclose(FILE * stream);
参1:打开文件的fp(fopen的返回值)
返回值:成功 :0, 失败: -1;
文件访问路径:
绝对路径:
从系统磁盘的 根盘符开始,找到待访问的文件路径
Windows书写方法:
1)C:\\Users\\afei\\Desktop\\06-文件分类.avi
2)C:/Users/afei/Desktop/06-文件分类.avi --- 也使用于Linux。
相对路径:
1)如果在VS环境下,编译执行(Ctrl+F5),文件相对路径是指相对于 day10.vcxproj 所在目录位置。
2)如果是双击 xxx.exe 文件执行,文件的相对路径是相对于 xxx.exe 所在目录位置。
示例
int main(void)
{
FILE* fp = NULL
fp = fopen("D:/itcast/test1.txt", "r")
if (fp == NULL)
{
perror("fopen error")
return -1
}
fclose(fp)
printf("-------------finish\n")
system("pause")
return EXIT_SUCCESS
}
按字符写文件 fputc:
int fputc(int ch, FILE * stream);
参1:待写入的 字符
参2:打开文件的fp(fopen的返回值)
返回值: 成功: 写入文件中的字符对应的ASCII码
失败: -1
练习:写26个英文字符到文件中。
示例
int main(void)
{
char* filename = "test04.txt"
int ret = 0
FILE * fp = fopen(filename, "w")
if (fp == NULL)
{
perror("fopen error")
return -1
}
for (size_t i = 0
{
fputc(65 + i, fp)
if (ret ==-1) //加上返回值可以增强程序的健壮性;
{
perror("fputc error")
return -1
}
}
fclose(fp)
system("pause")
return EXIT_SUCCESS
}
按字符读文件 fgetc
int fgetc(FILE * stream);
参1:待读取的文件fp(fopen的返回值)
返回值: 成功:读到的字符对应的ASCII码
失败: -1
文本文件的结束标记: EOF ---》 -1
示例
void write_file()
{
FILE* fp = fopen("05test.txt", "w");
if (fp == NULL)
{
perror("fopen error");
return;
}
fputc('a', fp);
fputc('b', fp);
fputc('c', fp);
fputc('d', fp);
fputc('e', fp);
fclose(fp);
}
void read_file()
{
char ch = 0;
FILE* fp = fopen("05test.txt", "r");
if (fp == NULL)
{
perror("fopen error");
return;
}
while (1)
{
ch = fgetc(fp);
if (ch == EOF)
{
break;
}
printf("%d\n", ch);
}
fclose(fp);
}
int main(void)
{
read_file();
system("pause");
return EXIT_SUCCESS;
}
feof()函数:
int feof(FILE * stream);
参1: fopen的返回值
返回值: 到达文件结尾--》非0【真】
没到达文件结尾--》0【假】
作用:
用来判断到达文件结尾。 既可以判断文本文件。也可以判断 二进制文件。
特性:
要想使用feof()检测文件结束标记,必须在该函数调用之前,使用读文件函数。
feof()调用之前,必须有读文件函数调用。
示例
void write_file()
{
FILE* fp = fopen("06test.txt", "w");
if (fp == NULL)
{
perror("fopen error");
return;
}
fputc('a', fp);
fputc('b', fp);
fputc(-1, fp);
fputc('d', fp);
fputc('e', fp);
fclose(fp);
}
void read_file()
{
char ch = 0;
FILE* fp = fopen("06test.txt", "r");
if (fp == NULL)
{
perror("fopen error");
return;
}
while (1)
{
ch = fgetc(fp);
if (feof(fp))
{
break;
}
printf("%d\n", ch);
}
fclose(fp);
}
int main(void)
{
read_file();
system("pause");
return EXIT_SUCCESS;
}
fgets()函数:
获取一个字符串, 以\n作为结束标记。自动添加 \0. 空间足够大 读\n, 空间不足舍弃\n, 必须有\0。
char * fgets(char * str, int size, FILE * stream);
char buf[10]; hello --> hello\n\0
返回值: 成功: 读到的字符串
失败: NULL
fputs()函数:
写出一个字符串,如果字符串中没有\n, 不会写\n。
int fputs(const char * str, FILE * stream);
返回值: 成功: 0
失败: -1
示例
int main(void)
{
char buff[10] = { 0 };
printf("%s", fgets(buff, 10, stdin));
char* str = "hello";
fputs(str, stdout);
system("pause");
return EXIT_SUCCESS;
}
练习: 获取用户键盘输入,写入文件。
假定:用户写入“:wq”终止接收用户输入,将之前的数据保存成一个文件。
FILE *fp = fopen("test07.txt", "w");
if (fp == NULL)
{
perror("fopen error");
return -1;
}
char buf[4096] = {0};
while (1)
{
fgets(buf, 4096, stdin);
if (strcmp(buf, ":wq\n") == 0)
{
break;
}
fputs(buf, fp);
}
fclose(fp);
示例
int main(void)
{
FILE* fp = fopen("test07.txt", "w");
if (fp == NULL)
{
perror("fopen error");
return;
}
char buff[4096] = { 0 };
while (1)
{
fgets(buff, 4096, stdin);
if (strcmp(buff, ":wq\n") == 0)
{
break;
}
fputs(buff, fp);
}
fclose(fp);
}
练习: 文件版四则运算:
1. 封装 write_file 函数,将4则运算表达式写入。
FILE * fp = fopen("w");
fputs("10/4=\n", fp);
fputs("10+4=\n", fp);
....
fputs("10*4=\n", fp);
2. 封装 read_file 函数, 将4则运算表达式读出,拆分,运算,写回。
1) 读出:
FILE * fp = fopen("r");
while (1) {
fgets(buf, sizeof(buf), fp);
}
2) 拆分:
sscanf(buf, "%d%c%c=\n", &a, &ch, &b);
3) 根据运算符,得到运算结果
switch(ch) {
case '+':
a+b;
}
4) 拼接 结果到 运算式 上
char result[1024];
sprintf(reuslt, "%d%c%d=%d\n", a, ch, b, a+b);
5)将 多个带有结果的运算 拼接成一个字符串。
char sum_ses[4096];
strcat(sum_res,reuslt);
6) 重新打开文件, 清空原有 4则运算表达式
fclose(fp);
fp = fopen("w");
7) 将 拼接成一个字符串。写入到空的文件中
fputs(sum_res);
示例
void write_file()
{
FILE* fp = fopen("08test.txt", "w");
if (fp == NULL)
{
perror("fopen error");
return;
}
fputs("10/2=\n", fp);
fputs("10*3=\n", fp);
fputs("4-2=\n", fp);
fputs("10+2=\n", fp);
fclose(fp);
}
int calc(int a, int b,char ch)
{
switch (ch)
{
case '/':
return a / b;
case '+':
return a + b;
case '-':
return a - b;
case '*':
return a * b;
default:
break;
}
}
void read_file()
{
char buf[4096] = { 0 };
char result[4096] = { 0 };
int a, b,ret;
char ch;
char sum[4096] = { 0 };
FILE* fp = fopen("08test.txt", "r");
if (fp == NULL)
{
perror("fopen error");
return;
}
while (1)
{
fgets(buf, 4096, fp);
if (feof(fp))
{
break;
}
sscanf(buf, "%d%c%d=\n", &a, &ch, &b);
sprintf(result, "%d%c%d=%d\n", a, ch, b, calc(a,b,ch));
strcat(sum, result);
}
fclose(fp);
FILE* fp1 = fopen("08test.txt", "w");
if (fp1 == NULL)
{
perror("fopen error");
return;
}
fputs(sum, fp1);
fclose(fp1);
}
int main(void)
{
write_file();
getchar();
read_file();
system("pause");
return EXIT_SUCCESS;
}