c博客06-2019-结构体&文件

1.本章学习总结

1.1 学习内容总结

  • feof是C语言标准库函数,其原型在stdio.h中,其功能是检测流上的文件结束符,如果文件结束,则返回非0值,否则返回0。使用方法:feof(文件指针)
  • strchr函数功能为在一个串中查找给定字符的第一个匹配之处,函数包含在C 标准库 中,返回值是一个指向该字符串中第一次出现的字符的指针,如果字符串中不包含该字符则返回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.选择排序
    c博客06-2019-结构体&文件_第1张图片

2.冒泡排序
c博客06-2019-结构体&文件_第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 头文件介绍

函数 功能

c博客06-2019-结构体&文件_第3张图片

2.1.2 函数实现文件介绍

  • 随机数函数,用来返回一个随机数
    c博客06-2019-结构体&文件_第4张图片

  • 主函数
    c博客06-2019-结构体&文件_第5张图片
    c博客06-2019-结构体&文件_第6张图片
    c博客06-2019-结构体&文件_第7张图片

-登录函数
c博客06-2019-结构体&文件_第8张图片
c博客06-2019-结构体&文件_第9张图片

  • 功能函数
void FindIdiom(IDIOM* idiom)              传入结构体指针,从而完成寻找成语意思
void OutputIdiom(IDIOM idiom[])           输出所有的成语
IDIOM* InputIdiom(FILE* fp,IDIOM idiom[]) 将文件里的成语输入定义的结构体
int IdiomGame(IDIOM*idiom)                成语游戏

c博客06-2019-结构体&文件_第10张图片
c博客06-2019-结构体&文件_第11张图片
c博客06-2019-结构体&文件_第12张图片
c博客06-2019-结构体&文件_第13张图片
c博客06-2019-结构体&文件_第14张图片

2.2运行结果

c博客06-2019-结构体&文件_第15张图片

c博客06-2019-结构体&文件_第16张图片

c博客06-2019-结构体&文件_第17张图片

c博客06-2019-结构体&文件_第18张图片

c博客06-2019-结构体&文件_第19张图片

2.3大作业总结

  • 1.想要多次利用文件里的成语数据,于是让文件读取函数返回一个结构体数组名,但是刚开始定义了一个结构体变量去接收这个数组名导致错误,检查后定义了一个结构体指针。
  • 2.在读取成语文件时提示读取异常,检查后发现,成语文本中有一条成语后面没有跟“:”,导致程序崩溃。
  • 3.原本对结构体的定义和文件懵懵懂懂,在做完大作业之后,将很多疑难杂症都解决了。
  • 3.和上次的函数作业相比,这次界面效果比上次好了点,函数有分装在多个文件里,函数之间的联系更加紧凑了,不再是全为void类型。

你可能感兴趣的:(c博客06-2019-结构体&文件)