【PTA主观题】8-1 文件操作

题目要求

  1. 编写函数int input(FILE * fp),录入学生的信息,自定义录入结束方式,但至少包括学号、姓名、班级、分数和登录密码,并按照学号排序后以二进制方式存入stus.dat,函数返回学生数量;
  2. 定义函数void encrypt(char * file_plain, char * file_cipher),用于加密stus.dat的密码字段,其中file_cipher为密文文件标识,file_plain为明文文件标识,加密算法采用与密码进行异或的方式;
  3. 定义函数void decrypt(char * file_cipher, char * file_plain)解密文件;
  4. 定义函数 void show(char * file) 输出文件内容。

将以上几步代码粘贴到报告,并附上运行成功的截图。
注意代码风格和添加充足注释。

代码呈现
 

//C语言
#include<stdio.h>
#include <stdlib.h>
#include <string.h>

#define SIZE 100
//定义一个名为Student的结构体,用于存储学生信息。
typedef struct student 
{
    char id[SIZE];
    char name[SIZE];
    char class[SIZE];
    int score;
    char password[SIZE];
} Student;

//排序函数
void bubbleSort(Student* stu_list, int num)
{
    int i, j;
    Student temp;

    for (i = 0; i < num - 1; i++)
    {
        for (j = 0; j < num - i - 1; j++)
        {
            if (strcmp(stu_list[j].id, stu_list[j + 1].id) > 0)
            {
                // 交换两个学生信息
                temp = stu_list[j];
                stu_list[j] = stu_list[j + 1];
                stu_list[j + 1] = temp;
            }
        }
    }
}

//输入
int input(FILE* fp) 
{
    Student stu_list[SIZE];//结构体数据 便于排序
    Student stu;
    int num = 0;
    char end[4] = "end";//输入结束标志
    char buffer[SIZE];

    while (1)
    {
        printf("Enter student information (id, name, class, score, password):\n");
        fgets(buffer, SIZE, stdin);
        //从标准输入(stdin)中读取一行字符串并存储到指定的字符数组(buffer)中
        //fgets:从标准输入中逐行读取字符,直到遇到换行符(包括换行符在内)。
        //它会将读取的字符存储到指定的字符数组中,并自动在字符串末尾添加一个空字符('\0')表示字符串的结束。
        if (strncmp(buffer, end, 3) == 0) 
            //检查是否输入了结束标志,如果 buffer 的前3个字符与 end 的前3个字符完全相等,break
            break; 

        sscanf(buffer, "%s %s %s %d %s", stu_list[num].id, stu_list[num].name, stu_list[num].class, &stu_list[num].score, stu_list[num].password);
        //sscanf:从指定的字符串中读取数据并按照指定的格式进行解析
        //从buffer中按照格式化字符串解析出一个字符串,存储到stu.id中
        //忽略一个或多个空格字符(以此类推)
            
        num++;
    }
    // 按学号排序
    bubbleSort(stu_list, num);

    // 写入二进制文件
    fwrite(stu_list, sizeof(Student), num, fp);
    //fwrite:将结构体对象stu写入文件中。
    //size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream);
    //ptr:要写入数据的内存地址。buffer(数组名相当于地址)
    //size:每个元素的大小(以字节为单位)。sizeof(Student)
    //count:要写入的元素数量。1
    //stream:指向要写入数据的文件流。,fp
    return num;
}
void encrypt(char* file_plain, char* file_cipher) 
{
    FILE* fp1, * fp2;
    Student stu;
    int i;

    fp1 = fopen(file_plain, "rb");
    fp2 = fopen(file_cipher, "wb");
    //FILE *fopen(const char *filename, const char *mode);返回值:
    //如果文件成功打开,则返回一个指向 FILE 类型结构的指针,该指针用于后续对文件进行读写操作。
    //如果文件打开失败,则返回 NULL。
    //filename:表示要打开的文件名或文件路径的字符串。
    //mode:表示打开文件的模式的字符串。模式字符串可以是以下值之一(常见的模式):
    // "r"	只读模式(文件必须存在)
    //"w"	写入模式(如果文件存在则截断,不存在则创建)
    //"a"	追加模式(如果文件存在则在末尾追加,不存在则创建)
    //"rb"	二进制只读模式
    //"wb"	二进制写入模式
    //"ab"	二进制追加模式
    
   
    while (fread(&stu, sizeof(Student), 1, fp1))
    {//对于每个读取到的结构体,循环遍历其password成员中的每个字符,并对其进行异或加密操作
        for (i = 0; i < strlen(stu.password); i++)
        {
            stu.password[i] ^= 7; 
            //(使用异或运算符^和常数7)然后将加密后的结构体写入fp2指向的文件中。
        }
        fwrite(&stu, sizeof(Student), 1, fp2);
    }
    //关闭文件指针fp1和fp2
    fclose(fp1);
    fclose(fp2);
}

void decrypt(char* file_cipher, char* file_plain)
{
    FILE* fp1, * fp2;
    Student stu;
    int i;

    fp1 = fopen(file_cipher, "rb");
    fp2 = fopen(file_plain, "wb");

    while (fread(&stu, sizeof(Student), 1, fp1))
    {
        for (i = 0; i < strlen(stu.password); i++)
        {
            stu.password[i] ^= 7; // 与密码进行异或解密
        }
        fwrite(&stu, sizeof(Student), 1, fp2);
    }

    fclose(fp1);
    fclose(fp2);
    //int fclose(FILE *stream);
    // stream 是一个指向 FILE 类型结构的指针,该指针是由 fopen 函数返回的。
    //如果关闭成功,则返回 0;否则,返回一个非零值。

}

void show(char* file) {
    FILE* fp;
    Student stu;

    fp = fopen(file, "rb");

    while (fread(&stu, sizeof(Student), 1, fp) == 1) {
        printf("ID: %s\n", stu.id);
        printf("Name: %s\n", stu.name);
        printf("Class: %s\n", stu.class);
        printf("Score: %d\n", stu.score);
        printf("Password: %s\n", stu.password);
        printf("--------------------\n");
    }

    fclose(fp);
}

int main() 
{
    FILE* fp;
    int num;
    char file_plain[] = "stus.dat";
    char file_cipher[] = "stus_cipher.dat";

    // 输入学生信息并存储到二进制文件中
    fp = fopen(file_plain, "wb");
    num = input(fp);
    fclose(fp);

    // 对密码字段进行加密
    encrypt(file_plain, file_cipher);

    // 输出加密后的文件内容
    printf("Encrypted file content:\n");
    show(file_cipher);

    // 对加密后的文件进行解密
    decrypt(file_cipher, file_plain);

    // 输出解密后的文件内容
    printf("\nDecrypted file content:\n");
    show(file_plain);

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值