c博客06-2019-结构体&文件
1.本章学习总结
1.1 学习内容总结
- feof是C语言标准库函数,其原型在stdio.h中,其功能是检测流上的文件结束符,如果文件结束,则返回非0值,否则返回0。使用方法:feof(文件指针)
- strchr函数功能为在一个串中查找给定字符的第一个匹配之处,函数包含在C 标准库 <string.h>中,返回值是一个指向该字符串中第一次出现的字符的指针,如果字符串中不包含该字符则返回NULL空指针。使用方法:strchr(指针,字符)
- strcmp函数可以比较两个字符串是否相等,若相等返回0。使用方法:strcmp(字符串1,字符串2)
-结构体的定义:
struct 结构名 {
类型名 结构成员名1;
类型名 结构成员名2;
…
类型名 结构成员名n;
};
-结构体变量的定义
<1>单独定义
单独定义是指先定义一个结构类型,再定义这种结构类型的变量。
一般形式为:
struct 结构名 {
类型名 结构成员名1;
类型名 结构成员名2;
…
类型名 结构成员名n;
};
struct 结构名 结构变量名表;
<2>混合定义
混合定义是指在定义结构类型的同时定义结构变量。
一般形式为:
struct 结构名 {
类型名 结构成员名1;
类型名 结构成员名2;
…
类型名 结构成员名n;
} 结构变量名表;
<3>无类型名定义
无类型名定义是指在定义结构变量时省略结构名,定义结构类型并且同时定义结构变量。
一般形式为:
struct {
类型名 结构成员名1;
类型名 结构成员名2;
…
类型名 结构成员名n;
} 结构变量名表;
###第3种定义形式省略了结构名。要注意的是,由于没有给出结构名,在此定义语句后面无法再定义这个类型的其他结构变量,除非把定义过程再写一遍。###
- 结构体成员的赋值方式
1.依次给每一个结构体成员变量进行赋值
2.使用已有的结构体变量给另一个结构体变量赋值(结构体变量之间是可以相互赋值) - 结构体数组排序(以课本上的学生成绩系统为例)
1.选择排序
2.冒泡排序
- 结构体指针
定义:
struct student
struct student *p;
p=&s1;
结构指针的值实际是结构变量的首地址,即第一个成员的地址,有了结构指针的定义,既可以通过结构变量s1直接访问结构成员,也可以通过结构指针变量p间接访问它所指向的结构变量中的各个成员。
具体形式:
(*p).num//一定要加括号,因为优先级不一样
或
p->num
或
s1.num
- 共用体
共用体定义:
union 联合名
{
成员声明;
成员声明;
}变量列表;
共用体特点:
1.利用覆盖技术,讲几个变量相互覆盖,这种几个不同的变量共同占用一段内存的结构类型。
2.共用体变量的地址和它的成员都是同一地址。
3.共用体变量中起作用的成员都是最后一次存放的成员,存入一个新成员后,原有的成员就会失去作用。
作用:节省内存。
- 枚举类型
定义:
enum 枚举名 { 枚举值1, 枚举值2, ...} 变量列表
例如:
enum weekday{sun,mon,tue,wed,thu,fri,sat};
定义了一个枚举类型名 enum weekday,然后定义变量为该枚举类型。
例如:
enum weekday day;
当然,也可以直接定义枚举类型变量。
例如:
enum weekday{sun,mon,tue,wed,thu,fri,sat} day;
其中,sum,mon,…,sat 等称为枚举元素或枚举常量,它们是用户定义的标识符。
- 文件打开
fp = fopen("idiom清洗版.txt", "r+");
fp1 = fopen("user.txt", "r+");
if (fp == NULL && fp1 == NULL)//判断文件是否打开
{
printf("open file error!\n");
exit(1);
}
- 将文件写入结构体
typedef struct
{
char idioms[10];
char content[200];
}IDIOM;
IDIOM* InputIdiom(FILE* fp,IDIOM idiom[])//将文件里的成语输入定义的结构体
{
FILE* f;
f = fp;
int i, j, k;
i = j = k = 0;
char temp[500];
char* loc;
while (feof(f) == 0)
{
fgets(temp, 500, f);
loc = strchr(temp, ':');
j = loc - temp;
for (i = 0; i < j; i++)
{
idiom[k].idioms[i] = temp[i];
}
idiom[k].idioms[i] = '\0';
strcpy(idiom[k].content, temp + j + 1);
k++;
}
return idiom;
}
- 重定位文件首函数rewind(文件指针)
- 指针移动控制函数fseek()
格式:
fseek(fp,offset,from);
offset表示文件偏移量,是long类型,offset可为负值,表示反向偏移,from表示从哪个位置开始计算偏移量,SEEK-SET,SEEK_CUR,SEEK_END,分别表欧式文件首部,当前位置。文件尾部。
- 获取指针当前位置函数ftell()
- 文件末尾检测函数feof(文件指针)
1.2 本章学习体会
- 像数组和指针一样,结构也是一种构造数据类型,它与数组的区别在于:数组中所有元素的数据类型必须是相同的,而结构中各成员的数据类型可以不同。
- 要熟练应用结构体指针,在文件读取到结构体之后,可以重复利用结构体指针,节省了时间
- 本周代码量在600左右
2.综合作业--“我爱成语”
2.1文件介绍
==========
2.1.1 头文件介绍
函数 | 功能 |
---|---|
2.1.2 函数实现文件介绍
-
随机数函数,用来返回一个随机数
-
主函数
-登录函数
- 功能函数
void FindIdiom(IDIOM* idiom) 传入结构体指针,从而完成寻找成语意思
void OutputIdiom(IDIOM idiom[]) 输出所有的成语
IDIOM* InputIdiom(FILE* fp,IDIOM idiom[]) 将文件里的成语输入定义的结构体
int IdiomGame(IDIOM*idiom) 成语游戏
2.2运行结果
2.3大作业总结
- 1.想要多次利用文件里的成语数据,于是让文件读取函数返回一个结构体数组名,但是刚开始定义了一个结构体变量去接收这个数组名导致错误,检查后定义了一个结构体指针。
- 2.在读取成语文件时提示读取异常,检查后发现,成语文本中有一条成语后面没有跟“:”,导致程序崩溃。
- 3.原本对结构体的定义和文件懵懵懂懂,在做完大作业之后,将很多疑难杂症都解决了。
- 3.和上次的函数作业相比,这次界面效果比上次好了点,函数有分装在多个文件里,函数之间的联系更加紧凑了,不再是全为void类型。