(五)C语言之联合体,枚举与IO

温馨提示

写博客是为了记录在开发过程中所涉及到的技术以及遇到的问题的解决,如果该博客对您有所帮助,希望可以点个关注/喜欢;如果您对文章中的内容有什么不同的见解,欢迎留言进行讨论。谢谢!

(五)C语言之联合体,枚举与IO

一、联合体(共用体)

1、定义

不同类型的变量共同占用一段内存(相互覆盖),联合变量任何时刻只有一个成员存在,节省内存

2、大小

联合体变量的大小=最大的成员所占的字节数

union MyValue{
    int x;
    int y;
    double z;
};

void main(){
    union MyValue d1;
    d1.x = 90;
    d1.y = 100;
    printf("%d,%d,%lf\n",d1.x,d1.y,d1.z);
    d1.z = 25.8;
    printf("%d,%d,%lf\n",d1.x,d1.y,d1.z);
    getchar();
}

输出结果为:

100,100,-92559592117433135502616407313071917486139351398276445610442752.000000
-858993459,-858993459,25.800000

根据上面代码可得出结论:在联合体中,最后一次赋值有效

二、枚举

1、定义

“枚举”就是把可能的值(固定的数据)一一的列举出来,变量的值只限于列举出来的值的范围

例如:

enum Day{
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday,
    Sunday
};

void main(){
    enum Day d = Wednesday;
    printf("Today is %d,%#x\n",d,&d);
    getchar();
}

三、IO操作

1、读取文本文件

参考文档

读取文件的方法为:

FILE * fopen(char * path,char * model)

void main(){
    char path[] = "D:\\test.txt";
    //打开 
    FILE *fp = fopen(path,"r");
    if(fp == NULL){
        printf("文件打开失败...\n");
        return;
    }
    //读取
    char buff[50];//缓冲
    while(fgets(buff,50,fp)){
        printf("%s",buff);
    }
    //关闭
    fclose(fp);
    getchar();
}

2、写入文本文件

参考文档

写入文件的方法为:

fputs(char * text,FILE * _file)

void main(){
    char path[] = "D:\\test_new.txt";
    //打开 
    FILE *fp = fopen(path,"w");
    if(fp == NULL){
        printf("文件打开失败...\n");
        return;
    }
    //写入
    char *text = "How are you?\nI am fine,Thank You!";
    fputs(text,fp);
    //关闭
    fclose(fp);
    getchar();
}

3、操作二进制文件

  • 计算机的文件存储在物理上都是二进制;文本文件和二进制之分,其实是一个逻辑之分

  • C读写文本文件与二进制文件的差别仅仅体现在回车换行符

  • 写文本时,每遇到一个’\n’,会将其转换成’\r\n’,(回车换行)

  • 读文本时,每遇到一个’\r\n’,会将其转换成’\n’

size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
参考文档
参数:

  • ptr :
    指向大小至少为(size * count)个字节的内存块的指针,转换为void *。
  • size :
    要读取的每个元素的大小(以字节为单位)。
    size_t是无符号整数类型。
  • count :
    元素数量,每个元素的大小为字节大小。
    size_t是无符号整数类型。
  • stream:
    指向指定输入流的FILE对象的指针。

size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
参考文档
参数:

  • ptr :
    指向大小至少为(size * count)个字节的内存块的指针,转换为void *。
  • size :
    要读取的每个元素的大小(以字节为单位)。
    size_t是无符号整数类型。
  • count :
    元素数量,每个元素的大小为字节大小。
    size_t是无符号整数类型。
  • stream:
    指向指定输入流的FILE对象的指针。
void main(){
    char read_path[] = "D:\\avatar.jpg";
    char write_path[] = "D:\\avatar_new.jpg";
    //读的文件,b字符表示操作二进制文件(binary)
    FILE *read_fp = fopen(read_path,"rb");
    
    //写的文件
    FILE *write_fp = fopen(write_path,"wb");;
    //复制
    int buff[50];//缓冲区域
    int len = 0;//每次读到的内容的长度
    while((len = fread(buff,sizeof(int),50,read_fp))!=0){
        //将读取到的内容写入新文件
        fwrite(buff,sizeof(int),50,write_fp);
    }
    //关闭
    fclose(read_fp);
     fclose(write_fp);
    getchar();
}

4、获取文件的大小

重新定位文件指针:

int fseek ( FILE * stream, long int offset, int origin );

参数:

  • stream:
    指向标识流的FILE对象的指针。
  • offset:
    二进制文件:从原点偏移的字节数。
    文本文件:零或ftell返回的值
  • origin:
    位置用作偏移的参考。 它由<cstdio>中定义的以下常量之一指定,专门用作此函数的参数:
ConstantReference position
SEEK_SET文件开头
SEEK_CUR文件指针的当前位置
SEEK_END文件结束

*允许库实现无意义地支持SEEK_END(因此,使用它的代码没有真正的标准可移植性)。

返回当前的文件指针,相对于文件开头的位移量:

long ftell ( FILE * stream);

void main(){
    char read_path[] = "D:\\avatar.jpg";
    FILE *fp = fopen(read_path,"r");
    //重新定位文件指针
    fseek(fp,0,SEEK_END);
    //返回当前的文件指针,相对于文件开头的位移量
    long filesize = ftell(fp);
    printf("filesize = %d\n",filesize);
    getchar();
}

5、文本文件的加密解密

//加密
void crypt(char normal_path[], char crypt_path[]) {
    //打开文件
    FILE *normal_fp = fopen(normal_path, "r");
    FILE *crypt_fp = fopen(crypt_path, "w");
    //一次读取一个字符
    int ch;
    while ((ch = fgetc(normal_fp)) != EOF) {//End of FILE
        //加密
        fputc(ch ^ 9, crypt_fp);
    }
    fclose(normal_fp);
    fclose(crypt_fp);
}

//解密
void decrypt(char crypt_path[], char decrypt_path[]) {
    //打开文件
    FILE *crypt_fp = fopen(crypt_path, "r");
    FILE *decrypt_fp = fopen(decrypt_path, "w");
    //一次读取一个字符
    int ch;
    while ((ch = fgetc(crypt_fp)) != EOF) {//End of FILE
        //加密
        fputc(ch ^ 9, decrypt_fp);
    }
    fclose(crypt_fp);
    fclose(decrypt_fp);
}

void main() {
    char normal_path[] = "D:\\test.txt";
    char crypt_path[] = "D:\\test_crypt.txt";
    char decrypt_path[] = "D:\\test_decrypt.txt";
    crypt(normal_path, crypt_path);
    decrypt(crypt_path, decrypt_path);
    getchar();
}

6、二进制文件的加密解密

读取二进制文件中的数据时,一个一个字符读取
密码:qazwsx

//加密
void crypt(char normal_path[], char crypt_path[], char password[]) {
    //打开文件
    FILE *normal_fp = fopen(normal_path, "rb");
    FILE *crypt_fp = fopen(crypt_path, "wb");
    //一次读取一个字符
    int ch;
    int i = 0;
    int pwd_len = strlen(password);
    while ((ch = fgetc(normal_fp)) != EOF) {//End of FILE
        //加密
        fputc(ch ^ password[i % pwd_len], crypt_fp);
        i++;
    }
    fclose(normal_fp);
    fclose(crypt_fp);
}

//解密
void decrypt(char crypt_path[], char decrypt_path[], char password[]) {
    //打开文件
    FILE *crypt_fp = fopen(crypt_path, "rb");
    FILE *decrypt_fp = fopen(decrypt_path, "wb");
    //一次读取一个字符
    int ch;
    int i = 0;
    int pwd_len = strlen(password);
    while ((ch = fgetc(crypt_fp)) != EOF) {//End of FILE
        //加密
        fputc(ch ^ password[i % pwd_len], decrypt_fp);
        i++;
    }
    fclose(crypt_fp);
    fclose(decrypt_fp);
}

void main() {
    char password[] ="qazwsx";
    char normal_path[] = "D:\\avatar.jpg";
    char crypt_path[] = "D:\\avatar_crypt.jpg";
    char decrypt_path[] = "D:\\avatar_decrypt.jpg";
    crpypt(normal_path, crypt_path,password);
    decrypt(crypt_path, decrypt_path,password);
    getchar();
}
    原文作者:onestravel
    原文地址: https://www.jianshu.com/p/5b0a86244140
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞