20160301.CCPP体系详解(0040天)

程序片段:01.fscanfprintf.c+02.51Job.c+03.7K7K.c
内容概要:fscanffprintf

///01.fscanfprintf.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>  
#include <stdlib.h>

//演示:scanf();&printf();--fscanf();&fprintf();:
void main01()
{
    //printf("Hello!");//(1).printf();函数默认向显示器打印,还可以向打印机打印[将显示器设备当做文件进行处理]
    //fprintf(stdout, "Hello!");//(2).这儿是往stdout文件打印Hello字符串,出现打印效果和printf();一样,说明printf();只是fprintf();的一种特殊情况

    char str[100] = { 0 };
    //scanf("%s", str);
    //(3).这里会直接退出,因为格式不对应的特点:
    //      需要输入a=abc,才能正常的抽取对应位置的字符串,
    //      根据指定格式进行所需字符串的抽取操作-->
    //      从指定格式的字符串当中抽取指定位置[%s]的内容
    fscanf(stdin, "a=%s", str);//(4).扫描键盘文件缓冲区的内容-->键盘缓冲区内容[注意格式对应关系,否则无法扫描到所需内容]-->整个字符串都在键盘缓冲区当中-->然后fscanf();扫描文件缓冲区,根据%s进行键盘缓冲区内容的提取操作
    //printf("%s", str);
    fprintf(stdout, "%s", str);//(5).printf();常规打印输出方式,fprintf():指定打印输出,将int&string映射到一个字符串-->再将该字符串打印到显示器设备文件缓冲区

    getchar();//(6).退出原因,接收了回车符之后发出退出动作
    getchar();//(7).显示器和键盘-->就是一个最直接的抽象文件缓冲区-->直接进行实时操作-->没有具体的磁盘文件对应

    system("pause");
}

//演示:sscanf();&sprintf();
void main02()
{
    char str[256] = { 0 };
    {
        //对字符串[1 mndadmin@yahoo.com.cn  xijaxi16ytja6t7ibcrj]进行处理
        //(1).匿名代码块儿的使用:划分变量的作用域
        int i = 0;
        char email[100] = "mndadmin@yahoo.com.cn";
        char pass[100] = "xijaxi16ytja6t7ibcrj";
        //(2).如何实现字符串的加法?-->字符串合并
        char str[256] = { 0 };
        //(3).细节:sprintf();不需要取地址,scanf();才需要地址
        sprintf(str, "%d %s %s", i, email, pass);
        //(4).早期:还有一个特殊的显示器设备:
        //      除了stdout以外-->查看标准定义-->在C&C++里面
        //      同样有个类似的操作符,用户向显示器设备打印数据
        //      和操作设备的原理一样,打印多个的原理是一样的效果
        fprintf(stdout, "\n %s", str);
        //(5).块儿语句的操作与使用+字符串汇总进去[fprintf:字符串汇总]
    }
    {
        //(1).字符串挖掘出来[fscanf();&fprintf();用于字符串数据挖掘]
        int j;
        char emailx[100] = { 0 };
        char passmd5[100] = { 0 };
        //(2).scanf();函数会遇到空格就结束扫描动作-->不要使用空格
        sscanf(str, "%d%s%s", &j, emailx, passmd5);//(3).字符串挖掘出来
        fprintf(stdout, "\n j=%d emailx=%s passmd5=%s", j, emailx, passmd5);//(4)字符串映射出来
    }

    system("pause");
}





//一.FScanf()FPrintf();
//01.如何对数据进行切割操作?
//      1.数据切割-->数据合并-->51Job数据
//      2.数据类型分析:切割之前首选需要对行数据字符串进行待处理类型分析
//              1           mndadmin@yahoo.com.cn           xijaxi16ytja6t78bcrj
//         (1).类型int                    char[]                                  char[]      
//     (2).空格作为字符串的[分割标识符],从而根据分割标识符进行数据分割
//02.数据操作:
//      1.fgets(pfr);-->获取一行字符串-->转换为int类型-->字符串截取-->很苦逼
//      2.fgets(pfr);-->新函数的引入:fscanf();&fprintf();
//          fscanf();&fprintf();都是用于往"文件里面"写入内容的-->操作对象:文件
//          特殊:printf();&fprintf():的本质差别是什么?
//              (1)C语言将所有的设备都抽象成为了文件进行处理
//              (2)printf();操作的是指定的设备:显示器,然而fprintf();可以手动指定操作
//                  的文件是什么!
//03.设备文件说明:
//          键盘:stdin
//      显示器:stdout
//          错误:stderr->实质还是显示器
//04.printf();是具备默认的操作设备:显示器stdout
//      printf();有固定的操作设备,fprintf();没有固定的操作设备
//05.sprintf();打印到字符串数组-->其实就是一个缓冲区
//06.sscanf();&sprintf();:操作对象都是字符串
//      sscanf();从指定格式的字符串当中取出指定位置占位符的相应字符串
//      sprintf();将int数值string数值的字符串映射到一个字符串当中
//      注意不同的字符串缓冲区操作特点
//07.MD5加密&邮箱&编号:
//      垃圾邮件发送:编号提取&邮箱提取
//08.另外两个很重要的字符串操作函数:sscanf();sprintf();
//      sscanf();//抽离出来
//      sprintf();打印过去
//09.分析:
//      (1)数据存储进结构体当中
//      (2)昨天的方式是遇到空格就替换为'\0'-->苦逼的操作
//      (3)今天使用sscanf();&sprinf();--------->简单的多
//10..处理51Job,轻量级的数据
//11.总结:
//      文件操作:
//          fscanf();&fprintf();-->特例:scanf();printf();
//      字符操作:
//          sscanf();&sprintf();
//      特别注意:
//          printf();操作字符串的时候不需要使用地址
///02.51Job.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>  
#include <stdlib.h>

//1.行数据结构体:
typedef struct jobinfo
{
    int id;
    char email[50];
    char password[50];
}INFO, *PINFO;//INFO结构体,PINFO指向结构体的指针

void main03()
{
    //(1)calloc();开辟的堆内存会自动清零
    PINFO p = calloc(2435, sizeof(INFO));
    FILE *pfr = fopen("D:\\TestData\\DB\\51Job\\51job0.txt", "r");
    FILE *pfw = fopen("D:\\TestData\\51JobTest.txt", "w");
    for (int i = 0; i < 2435; i++)
    {
        //(2)从pfr文件指针指定的行数据当中扫描数据,每次扫描一行的字符串数据,然后对字符串数据根据制定的占位符格式进行数据提取挖掘
        fscanf(pfr, "%d%s%s", &p[i].id, p[i].email, p[i].password);//(3)fscanf();就是数据挖掘作用-->对字符串当中指定位置数据挖掘-->依然是一次扫描一行的数据内容,然后按照指定格式进行解析[去除掉了空格数据]
        //fprintf(stdout, "%d %s %s \n", p[i].id, p[i].email, p[i].password);//(4)这里只要将stdout更换为文件指针就可以写入到指定的文件当中//-->复制操作
        fprintf(pfw, "%d %s \n", p[i].id, p[i].email);
    }
    fclose(pfr);
    fclose(pfw);//(5)强制将文件指针所操作的缓冲区内容刷新到新文件当中

    system("pause");
}





//01.处理51Job的数据:2000多行
//      1.解决51Job数据:将51Job当中的数据逐行挨个提取到一个结构体数组当中
//      2.按行进行数据行切割,防止数据乱七八糟-->按行提取到结构体
//02.操作流程:
//      1.将51Job当中的所有数据直接载入进内存-->开辟内存:
//          不能直接在栈内存开辟,因为栈内存空间太小
//      2.挖掘[fscanf]-->映射[fprintf]
//03.挖掘数据-->再次打印:数据扫描操作fscanf();
//      群发邮件需要进行数据挖掘操作-->只需要Email这么一个数据
//04.fscanf();&fprintf();
//      1.细节说明:添加编号方式
//      2.7K7K           数据库-->小游戏网站-->都有邮箱密码-->添加编号-->管理有多少行:
//      3.数据处理方案7K7K.txt-->垃圾数据剔除
//      4.读取文件-->添加编号-->写入文件-->不需要改变每一行
//      5.还有空格终止的情况-->以回车符作为行数据结尾标识符
///03.7K7K.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>  
#include <stdlib.h> 

typedef struct info7k7k
{
    char user[50];
    char pass[50];
}INFO, *PINFO;

void main04()
{
    //(1)为结构体添加编号:数据筛选之后,在进行数据从新写入动作的时候进行编号处理动作
    FILE *pfr = fopen("D:\\TestData\\DB\\7K7K\\1-5.txt", "r");
    FILE *pfw = fopen("D:\\TestData\\7k7kTest.txt", "w");

    int i = 0;
    while (!feof(pfr))
    {
        i++;
        INFO info1;//临时数据载体结构体
        //(2)注意这里的scanf();遇到空格&回车符都会终止扫描动作
        fscanf(pfr, "%s%s", info1.user, info1.pass);//使用fscanf();进行文件指针指向的数据行按照指定格式进行数据挖掘
        fprintf(pfw, "%d %d %s \n", i, info1.user, info1.pass);//组合-->添加额外的信息[索引]
    }
    fclose(pfr);
    fclose(pfw);

    system("pause");
}

void main05()
{
    //int num = fprintf(stdout, "Hello World %s !", "1234");
    //printf("\n %d", num);//(1)18-->fprintf();成功打印到指定文件当中的字符个数
    //(2)fprintf();打印成功的字符个数统计特点,除开结尾字符与占位字符,累加第二个,第三个字符串的长度

    //(3)这儿不能读取一个没有存在的文件,否则会报异常-->在执行这条语句的时候,就会判断操作的文件是否存在
    //FILE *pfr = fopen("D:\\TestData\\x.txt", "r");//读取模式起先不执行判断动作,但是写入操作的时候会预先进行判断文件是否存在,不存在就默认进行创建,再执行下一步,"r" 模式会在执行frpintf();的时候判断文件是否存在,如果不存在,就直接报错
    //(4)操作模式:以读取的模式打开一个文件是不能够进行数据写入操作的
    //      也就是说写入失败返回-1,注意模式对应着操作关系            
    //      fprintf();写入模式的情况下进行打印写入操作会返回-1
    //int num = fprintf(pfr, "Hello World %s !", "1234");
    //printf("\n%d", num);

    system("pause");
}

void main06()
{
    //char str[128] = { 0 };
    //(1)返回值是扫描到几个数据,不管你有多长,只当做是一个数据进行解读,
    //       也就是满足多少个占位符的数据就最多有多少个
    //int numa;
    //int numb;
    //int num = fscanf(stdin, "%d%s%d", &numa, str, &numb);//这里同样会以空格,回车符作为结尾的特点
    //printf("\n str=%s numa=%d numb=%d num=%d", str, numa, numb, num);

    FILE *pfr = fopen("D:\\TestData\\x.txt", "w");
    //(2)返回值为-1说明扫描失败[fscanf();-->-1-->扫描读取失败||fprintf();-->-1-->打印写入失败]
    char str[128] = { 0 };
    int numa;
    int numb;//(3)fscanf();的操作文件如果不是stdin就不会有等待用户输入的特点
    int num = fscanf(pfr, "%s%d%d", str, &numa, &numb);
    printf("\n %d", num);

    system("pause");
}





//二.fscanffprintf实战以及返回值:
//01.数据特点:需要整齐的数据,避免操作异常数据
//      1.可以进行行数据的扫描-->统计操作
//      2.email&password-->找出密码出现次数最多的密码
//      3.形成密码库-->用户破解邮箱-->因为用过一次的密码
//          其它地方用的可能性非常大
//02.对首行每列的数据类型进行势识别,然后再进行数据处理
//      数据处理-->也许有些时候中间少了一行也就造成了读取
//      中断,或者没能够识别到相应的数据
//03.两行数据正常-->三行数据不再正常:垃圾数据
//      数据自定义的预先处理,防止后期数据处理异常
//04.fscanf();&fprintf();
//      fscanf();数据挖掘
//      fprintf();数据组合-->完善-->检测多少个空格
//05.fscanf();&fprintf();另外一个功能:
//      fprintf();//返回的是成功写入的字符个数

程序片段(02):01.perror+02.ferror.c+03.clearerror.c
内容概要:文件出错

///01.perror.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include    <stdlib.h>

void main01()
{
    FILE *pfw = fopen("D:\\TestData\\51Job.txt", "w");//(1)在这里就预先进行了判断动作,首先判断51Job.txt这个文件在不在,如果在就不创建51Job.txt,如果不在就创建51Job.txt这个文件
    if (pfw == NULL)//(2)如果原始文件是一个只写的文件,在这里采用读取的模式是无法创建pfr的,如果原始文件是一个只读的文件,在这里是无法采用写入的模式创建pfr
    {
        perror("错误是");//(3)权限冲突:以写入的方式打开一个只具备读取模式的文件[perror:用于提示文件出错信息(permission denied:拒绝许可!)]
    }
    fputs("HaiHua", pfw);//(4)错误信息:操作一个未能创建的pfw对象,会报出一个窗口错误
    fclose(pfw);

    system("pause");
}



//三.文件异常:
//01.文件出错的几种情况:perror&ferror
//      1.打开模式与原始文件的访问权限不匹配-->控制台错误
//      2.操作一个未能成功创建的文件指针-->窗口错误
//02.perror解决文件出错的问题:
//      1.if(pf==NULL){perror("错误是");}
//      2.控制台显示:[错误是:permission denied]
//03.举例说明:51Job
//      1.以写入的模式打开一个只具备读取权限的文件
//      2.磁盘满载的情况
//      特点:perror都可以获取错误信息,并显示于控制台当中
//04.如何检测到错误信息?
//      1.编写的软件不仅需要在正常的情况之下工作,还需要
//          在错误的情况之下正常工作[异常的自动化处理解决方案]
//      2.编写软件的时候需要预先提升软件的容错特性,如果软件
//          崩溃了,需要先提示错误信息,再进行退出-->方便调试异常
//05.如何判断文件是否出错?
//      1.perror|ferror:
//          (1)perror:用于自定义的"处理异常信息"
//          (2)ferror:测试文件异常或者非异常[返回值特点:未出错0,出错非0]
//              自动处理异常信息,可以手动进行操纵
//      2.每次调用"输入输出"的时候就就会自动创建一个ferror:
//          每次打开的时候需要初始化ferror为0-->自我控制
///02.ferror.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>  
#include <stdlib.h>

//1.ferror:自动检测程序异常或者正常
//      特点:每执行"读写操作"的时候,都会"重新产生一个ferror"
//          返回值特点:0代表正常,1代表异常

void main02()
{
    //1.以写入的模式打开一个只读权限的文件:
    FILE *pfw = fopen("D:\\TestData\\51Job.txt", "w");
    FILE *pfr = fopen("D:\\TestData\\51Job.txt", "r");
    if (pfw == NULL)
    {
        printf("\n onlywrite open fail!");
    }
    else
    {
        printf("\n onlywrite open success!");
    }

    //2.在这儿同样会检测到异常信息,只不过这次没有进行手动检测,
    //      但是ferror();进行了自动检测-->写入异常-->触发了一个自动
    //      异常处理机制-->不过程序不能正常继续执行下去
    //fputc("123", pfw);
    //3.在这儿采用ferror();进行手动检测程序异常信息
    if (ferror(pfw) == 0)
    {//4.文件打开失败的情况之下,pfr=NULL,ferror(pfw);检测到异常
        //信息,手动处理异常信息,保证程序的正常执行,只不过具备异常
        //处理功能:0正常,1非正常
        printf("\n 写入正常!");
    }//5.使用ferror();手动操作异常,保证程序的正常执行,用户导致的错误,
    else//程序员进行控制处理
    {
        printf("\n 写入异常!");
    }
    //fputs("1234", pfw);//6.直接弹窗,阻止程序的继续执行

    if (ferror(pfr) == 0)
    {//6.这个代码用于检测程序的工作状态:正常|异常
        printf("\n 读取正常!");
    }
    else//7.异常的手动操作方式
    {
        printf("\n 读取异常!");
    }

    system("pause");
}



//01.测试文件是否能够正常打开:
//      1.文件指针是否为空的判定方式
//      2.ferror();判定方式-->ferror();每次读写操作都会自动初始为0
//          首次执行读写操作的时候创建ferror();-->以后自动初始化
//          -->自动检测异常信息
//02.为什么检测的时候就出现了异常?
//      1.如果没有ferror();不会弹出窗口提示异常错误信息!
//      2.perror();最多能够打印一条信息,但是ferror();会弹出一个异常信息
//          窗口-->比如文件流NULL的情况之下会弹出一个异常错误信息窗口
//      3.这儿的异常错误信息窗口的处理方式和C++当中的异常错误信息雷同
//03.错误与异常的区别:
//      1.错误:
//          (1)完全不能够进行编译,程序不能够直接跑起来
//          (2)逻辑错误,出现的结果预先判定错误特点,是你的代码问题
//      2.异常:
//          满足条件的时候,你的代码可以执行,不满足的情况下你的代码不能够
//          继续进行执行,我们进场调的异常比较多,而不是错误比较多[阻碍作用]
//04.使用ferror:
//      ferror:检测程序异常或者正常的情况
//05.假定一个文件出错了,如何将文件出错的情况重置?
//      异常出错信息的重置情况-->cleaner();-->
//      文件异常出错-->异常处理-->异常处理之后:需要cleaner继续执行
///03.clearerror.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h> 

//1.文件异常错误处理方式:
//      (1).perror:"提示"文件错误信息
//      (2).ferror:"检测"文件异常信息
//      (3).cleaner:"清除"文件异常信息
//2.总结:
//      检测ferror-->提示perror-->清除cleaner

void main()
{
    //FILE *pfw = fopen("D:\\TestData\\51Job.txt", "w");
    //if (pfw==NULL)
    //{
    //  perror("\n错误是");//"提示"文件错误信息
    //}
    //fputs("HaiHua!", pfw);

    //FILE *pfr = fopen("D:\\TestData\\51Job.txt", "r");
    //if (ferror(pfr)==0)
    //{
    //  //1.扫描异常:只读权限的文件,以只读的模式打开文件,再进行数据写入的时候,不会直接报错,但是会自动检测到异常状态
    //  //      ferror();函数检测异常信息的前提是,pfr对象必须能够被正常创建出来!
    //  printf("\n 只读正常!");
    //}
    //else
    //{
    //  printf("\n 只读异常!");
    //}
    //fclose(pfr);

    FILE *pf = fopen("D:\\TestData\\51Job.txt", "w+");
    if (pf==NULL)
    {
        perror("\n 错误是");//2."提示"文件出错信息
    }
    fputs("Hello China a", pf);//3.直接覆盖操作
    //rewind(pf);//4.移动文件指针到文件开头
    char ch = fgetc(pf);
    //5.如果没有到达文件末尾便一直进行单个字符的读取
    //      操作,这里需要构建一个文件异常,然后再进行异常清除
    //      peror:提示错误信息-->ferror:检测错误信息
    if (getc(pf)!=EOF)
    {
        //6.EOF有两种可能:
        //      (1)正常结束
        //      (2)读取出错
        if (feof(pf)==EOF)
        {
            printf("读取到文件结尾!");
            clearerr(pf);//7.重置流的状态
        }
        if (ferror(pf))
        {
            printf("异常!");
            clearerr(pf);//8.相当于让文件指针回到开头,爱你给出文件异常错误信息,相当于异常处理机制
        }
    }

    //char ch = fgetc(pf);
    //int ch = fgetc(pf);
    //if (ch==EOF)//手动检测错误
    //{
    //  printf("error");
    //}
    //fclose(pf);

    system("pause");
}



//01.clearerr:用于清除异常,等用于将文件指针移动到文件缓冲区开头
//      1.解决什么样儿的问题?-->假定文件操作失败-->需要进行恢复
//          文件的正常操作状态-->clearerr-->出现错误:权限错误清除
//      2.如何清除访问权限错误?
//          (1).只读权限的文件,采取写的模式打开,会直接出现异常
//          (2).只读权限的文件,采用读的模式打开,不会直接出现异常:
//              但是不会写入成功-->区分打开成功与否
//      3.细节了解:
//          文件:一段儿连续的数据-->fseek();移动到文件末尾
//              你读取到文件之外的字符就是异常
//02.什么情况之下经常使用到ferror&perror&clearerr?
//      尤其是处理大数据的时候经常遇到异常错误信息,这个时候
//      也就需要处理文件异常信息

程序片段(03):Unicode.c
内容概要:Unicode文件处理

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <string.h>

//1.文件操作函数归总:
//      窄字符:
//          打开&关闭:
//              fopen();        fclose();
//          单字符:
//              getchar();  putchar();
//          多字符:
//              fputs();        fgets();
//          文件:
//              fputc();        fgetc();
//              scanf();        printf();
//              fscnaf();       fprintf();
//      宽字符:
//          打开&关闭:
//              _wfopen();  fclose();
//          单字符:
//              getwchar(); putwchar();
//          多字符:
//              fgetws();       fputws();
//          文件:
//              fgetwc();       fputwc();
//              wscanf();   wprintf();
//              fwscanf();  fwprintf();                                           
//      二进制:
//          fwrite();       fread();

//窄字符处理:
void main01()
{
    FILE *pfr1 = fopen("D:\\TestData\\CeShi.txt", "r");
    FILE *pfr2 = fopen("D:\\TestData\\CeShi.txt", "rb");                                                            
    FILE *pfr3 = fopen("D:\\TestData\\CeShiTest.txt", "r");//1.按照r这种读取模式会将\r\n当做两个进行识别
    FILE *pfr4 = fopen("D:\\TestData\\CeShiTest.txt", "rb");//2.按照rb这种读取模式会将\r\n分开当中识别
    //int i = 0;
    while (!feof(pfr1))
    {
        //i++;
        char ch = fgetc(pfr1);
        putchar(ch);
    }
    //printf("len=%d", i);
    fclose(pfr1);

    system("pause");
}

//宽字符处理:
void main02()
{
    //1.处理宽字符的第一步:
    setlocale(LC_ALL, "zh-CN");
    //2.宽字符的打开方式:
    FILE *pfw = _wfopen(L"D:\\TestData\\CeShiTest.txt", L"wb");
    FILE *pfr = _wfopen(L"D:\\TestData\\CeShi.txt", L"rb"); 
    while (!feof(pfr))//3.宽字符和窄字符判断文件结尾的方式一致
    {
        wchar_t ch = fgetwc(pfr);//获取宽字符
        putwchar(ch);//4.显示宽字符[显示到指定的显示器当中]-->putwchar();-->fputwc();简写形式
        fputwc(ch, pfw);//5.将宽字符输出到文件当中
    }//6.宽字符&窄字符的文件指针关闭方式一样
    fclose(pfr);
    fclose(pfw);
    system("D:\\TestData\\CeShiTest.txt");

    system("pause");
}

//宽字符处理
void main03()
{
    setlocale(LC_ALL, "zh-CN");
    FILE *pfr = _wfopen(L"D:\\TestData\\CeShi.txt", L"rb");//1.如果原始文件是采用窄字符写进去的,那么读取出来的时候如果采用宽字符,就不能够采用二进制方式进行读取,以防字符被拆分开来,需要采用字符读取模式进行数据读取
    while (!feof(pfr))
    {
        wchar_t wstr[256] = { 0 };
        fgetws(wstr, 256, pfr);
        wprintf(L"%ls", wstr);
    }

    system("pause");
}

//宽字符文件复制:
void main04()
{
    setlocale(LC_ALL, "zh-CN");
    FILE *pfr = _wfopen(L"D:\\TestData\\CeShi.txt", L"rb");
    FILE *pfw = _wfopen(L"D:\\TestData\\CeShiText.txt", L"wb");
    while (!feof(pfr))
    {
        wchar_t wstr[256] = { 0 };
        fgetws(wstr, 256, pfr);
        wprintf(L"%ls", wstr);
        fputws(wstr, pfw);//宽字符写入
    }
    fclose(pfr);
    fclose(pfw);
    system("D:\\TestData\\CeShiTest.txt");

    system("pause");
}

void main()
{
    //1.设置本地化:明确宽字符编解码的操作方式
    setlocale(LC_ALL, "zh-CN");
    //2.一定要添加L作为宽字符标识处理
    //wprintf(L"%ls", L"Hello 天朝!!!");
    //3.C语言将所有的设备都抽象为文件进行处理
    //fwprintf(stdout, L"%ls%d", L"海华", 100);
    wchar_t wstr[100] = { 0 };
    //fwscanf(stdin, L"%ls", wstr);//4.扫描键盘输入的宽字符字符串,初始化到wstr宽字符数组当中
    fwprintf(stdout, L"%s%d%s", L"海华", 100, wstr);//5.将宽字符数据映射到指定文件当中

    system("pause");
}



//三.Unicode文件处理:
//01.宽字符文件处理:
//      1.马化腾(pony)--Phone:13809899900--QQ:10001--Tecnent:一号
//      2.宽字符数据处理-->文件另存为-->保存格式分析:
//          文本文件(制表符分割)*.txt-->很多数据格式-->建议采用宽字符来进行存储
//          宽字符处理(Unicode数据处理方式)-->宽字符处理的标识:Unicode方式
//      3.杂乱无章的数据处理:
//          故障&劫持-->提示
//      4.处理宽字符数据的时候:
//          不能再使用fgetc();&fputc();进行数据处理
//      5.大多数的数据都是采用Unicode编码:
//          窄字符读取方式错误-->程序自动创建ferror();并且清零
//          然后检测异常信息[乱码:宽字符的原因--垃圾信息]
//          常规的fgetc();&fputc();不起到作用--编码问题
//02.Unicode文件处理:
//      1.现在的所有C语言教课书都不会介绍宽字符,因为它们
//          生在国外-->天朝需要处理宽字符问题
//      2.宽字符处理情况
//03.宽字符处理函数:
//      1.为什么以R的读取模式会提前结束?
//          因为它在这个时候,会有很多像-1这样的字符,很快就会读取到
//          文件的结尾-->数据天花乱坠
//      2.中文不存在:需要使用本地化
//          宽字符文件处理-->使用r照样读取出错-->Unicode都必须采用
//          二进制,因为Unicode编码的数据有很多空字符,读取的时候容易
//          误认为到了文件结束读取
//04.数据挖掘:
//      1.大数据文本文件-->数据挖掘-->生成有效的二进制结构体数据
//      2.进行信息对称[Unicode文本-->有效信息提取-->二进制结构体数组-->信息对称]
//      3.垃圾信息排除解决方案
//05.宽字符的使用情况?
//          窄字符---------宽字符
//      单字符处理
//          fgetc                   fgetwc
//          fputc                   fputwc
//      数据行处理
//          fgets                   fgetws
//          fputs                   fputws
//      数据处理[扫描-映射]
//          fscanf                  wfscanf
//          fprintf                 wfpritf
//      特殊情况:[二进制处理:没有宽窄字符之分]
//          fread                   fwrite
//06.掌握数据的处理和文件编码是处理跨平台的处理
//      跨平台:精通编码
//07.信息分类-->归纳-->总结-->推销
//      真实的数据信息
//08小结:
//      1.宽字符必须本地化
//      2.字符处理函数归纳
//      3.打开Unicode文本必须采用二进制的读取模式

程序片段(04):数据扫描.c
内容概要:数据扫描

#include <stdio.h>
#include <stdlib.h>

//1.数据挖掘预处理方案:
//      第一种:替换为空格
//      第二种:集合
//2.数据挖掘数据扫描方案:
//      scanf:
//          一般情况下,系统默认分配一个缓冲区,用于等待用户输入一长串数据
//          使用该缓冲区之后,缓冲区数据还在,所以需要手动清空这个缓冲区
//      下面两种数据扫描方案最常用:
//          sscanf();-->从字符串进行数据扫描
//          fscanf();-->从文件进行数据扫描
void main()
{
    //举例:char strall[300] = "123#456#789\n";
    char strall[300] = "123adadfdfa# 445468656yincheng01@163.com\n789\n";
    char name[100] = { 0 };
    char pass[100] = { 0 };
    char mail[100] = { 0 };
    //1.1234# 123#45a-->scanf();&fscanf();空格未能进行处理-->自动终止
    //      scanf("%s#%s#%s", name, pass, mail);
    //2.123#123#123-->没有空格的情况,需要进行完全匹配
    //     这里进行了整体识别进行匹配特点
    //printf("%s--%s--%s", name, pass, mail);
    //3.123#123#123-->name=123#123#123--pass= mail=
    //      把扫描到的数据当成了一个整体字符串进行处理
    //法一:
    //scanf("%s%s%s", name, pass, mail);//空格分割处理
    //法二:需要限定结束标识符
    scanf("%[0-9A-Za-z]%*[^#]");
    scanf("%[0-9A-Za-z]%*[^#]*[^0-9A-Z-a-z]%*[^#]", name, pass);



    system("pause");
}



//void main01()
//{
//  //scanf("%[0-9A-Za-z]%*[^#]*[^0-9A-Za-z]%*[^#]", name,pass);
//  //scanf("%[0-1A-Za-z]%*[^0-9A-Za-z]%[0-1A-Za-z]%*[^0-9A-Za-z]%[0-1A-Za-z]%*[^0-9A-Za-z]"), name, pass, mail;
//
//  //sscanf(strall, "%[0-9A-Za-z]%*[^0-9A-Za-z]%[0-9A-Za-z]%*[^0-9A-Za-z]%[0-9A-Za-z]%*[^0-9A-Za-z]", name, pass);
//  sscanf(strall, "%[0-9A-Z-a-z]%*[^0-9A-Za-z]%[0-9A-Z-a-z]%*[0-9A-Za-z]%[0-9A-Za-z@.]%*[^0-9A-Za-z]", name, pass, mail);
//  printf("name=%s--path=%s--mail=%s", name, pass, mail);
//
//  system("pause");
//}
//
演示两种数据挖掘方式
//void main()
//{
//  FILE *pf = fopen("D:\\TestData\\CSDN.txt", "r");
//  for (int i = 0; i < 100; i++)
//  {
//      char name[100] = { 0 };
//      char pass[100] = { 0 };
//      char mail[100] = { 0 };
//      //需要数据完整性才能这么玩儿
//      //fscanf(pf,"%[0-9A-Za-z]%*[^0-9A-Za-z]%[0-9A-Za-z]%*[^0-9A-Za-z]%[0-9A-Za-z@._]%*[^0-9A-Za-z]",name,pass,mail);
//      char allstr[500] = { 0 };
//      fgets(allstr, 500, pf);
//      sscanf(allstr, "%[0-9A-Za-z_]%*[# ][^0-9A-Za-z_]%[0-9A-Za-z_]%*[^0-9A-Za-z_]%[0-9A-Za-z@._]%*[^0-9A-Za-z_]");
//      pritnf("%s %s %s\n", name, pass, mail);
//  }
//  fclose(pf);
//
//  system("pause");
//}





//四.数据扫描:
//01.各种数据信息:信息扫描&筛选-->数据挖掘处理:
//      1.扫描数据-->不能够按照"字符串"的方式操作-->结构体
//      2.多种处理方法:格式是否整洁
//          (1)fscanf();&fprintf();
//          (2)数据筛选动作 
//      3.根据条件搜索数据:数据处理
//02.数据扫描:
//      1.根据条件进行判断
//      2.轻量级数据扫描演示
//      3.fscanf扫描高级技巧
//      4.重点问题:数据处理
//          scanf可以扫描一个集合:
//              原理:正则表达式
//          数据处理模型:
//              CSDN:zdg # 12344321 # zdg@csdn.net
//          扫描提取数据:
//03.scanf的几种表现形式:
//      scanf:只是用于键盘输入,起不了核心作用
//          具备缓冲区问题,需要实时清空缓冲区进行处理
//      sscanf:字符串扫描
//      fscanf:文件扫描
//04.解释:连续执行数据操作进行解析
//      举例:%[0-9A-Za-z]   %*[^0-9A-Za-z]
//      1.读取一个集合,遇到不是数字或者大小写字母就跳出
//      2.读取所有的非数字字母字符
//      3.类似于正则表达式
//05.常用的两种数据扫描方式:
//五.fscanfsscanf扫描数据:
//01.拼装组合数据
//02.数据处理流程:
//      分析:zdg # 12344321 # zdg@csdn.net
//      数字字母 空格采用*进行跳过  
//      跳过原理:先进行读取,再进行废弃
//      注意:scanf扫描键盘缓冲区,不会往前移动,某些情况之下
//          扫描往前进行会产生误差情况

程序片段(05):海华的妹子.c
内容概要:数据挖掘

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

char path[256] = "D:\\TestData\\BigData.txt";
//12770     1小姐     女       22      166     本科      未婚      合肥      山羊座     编辑
typedef struct haihualove
{
    char allstr[2048];//(1)包含全部数据信息,注意长度

    int id;//(2)待挖掘的数据信息
    char name[10];
    char sex[3];
    int age;
    int tall;
    char study[10];
    char mary[10];
    char where[10];
}H, *PH;

PH ph;//这人的ph不能是局部变量,因为函数运行完毕之后,会丢失数据

void init()
{
    PH ph = calloc(100, sizeof(H));//(1)开辟空间,堆内存
    FILE *pf = fopen(path, "r");
    for (int i = 0; i < 101; i++)
    {
        char str[2048] = { 0 };
        fgets(str, 2048, pf);
        if (i >= 1)
        {//(2)因为第一行是表头数据
         //(3)这里使用fgets();而不是使用fscanf();
         //因为fscanf();函数处理的都是整齐的数据
            /*char str[2048] = { 0 };//(4)这一步应当放在外面
            fgets(str, 2048, pf);*///因为我们需要跳过第一行数据
            //(6)这里不能扫描空白字符-->筛选空白字符
            //(7)数据规则化的处理
            strcpy(ph[i - 1].allstr, str);//(8)因为这里是从第一个开始,拷贝总串
            sscanf(str, "%d %s %s %d %d %s %s %s", &ph[i - 1].id, ph[i - 1].name, ph[i - 1].sex, &ph[i - 1].age, &ph[i - 1].tall, ph[i - 1].study, ph[i - 1].mary, ph[i - 1].where);//(5)注意这儿的某些数据需要传递地址
        }
    }

    fclose(pf);
}

void main01()
{
    FILE *pf = fopen(path, "r");
    while (!feof(pf))
    {
        char str[2048] = { 0 };//(1)读取的行字符串可能很长
        fgets(str, 2048, pf);
        printf("%s", str);
        pritnf("\n\n\n\n");

    }
    fclose(pf);

    system("pause");
}

void main02()
{                    
    PH ph = calloc(100, sizeof(H));//(1)开辟空间,堆内存
    FILE *pf = fopen(path, "r");
    for (int i = 0; i < 101; i++)
    {
        if (i>=1)
        {//(2)因为第一行是表头数据
            //(3)这里使用fgets();而不是使用fscanf();
            //因为fscanf();函数处理的都是整齐的数据
            char str[2048] = { 0 };
            fgets(str, 2048, pf);
            strcpy(ph[i - 1].allstr, str);//(4)因为这里是从第一个开始,拷贝总串
            sscanf(str, "%d %s %s %d %d %s %s %s", ph[i - 1].id, ph[i - 1].name, ph[i - 1].sex, ph[i - 1].age, ph[i - 1].tall, ph[i - 1].study, ph[i - 1].mary, ph[i - 1].where);
        }
    }

    fclose(pf);
    system("pause");
}

void main()
{
    init();
    for (int i = 0; i < 901; i++)
    {//(1)筛选条件的控制,各式各样的信息检索
        /*if (ph[i].age < 20 && ph[i].tall>165)
        {
            printf("%s", ph[i].allstr);
        }*/
        if (strcmp(ph[i].mary, "已婚") == 0)
        {
            printf("%s", ph[i].allstr);
        }
    }
}



//五.数据挖掘:
//01数据挖掘:解决问题
//      1.问题:空格+垃圾数据--数据挖掘
//      2.编程搞定数据挖掘-海华选妹子
//02数据挖掘:数据扫描
//      1.数据挖掘处理-->扫描-->筛选-->挖掘
//      2.筛选条件查询-->路径
//03之前方式的缺点:
//      1.只能对比指定字符串是否出现的情况
//      2.普通数据挖掘方式的特点
//04数据搜索特点:
//      1.多条件查询:名称+年龄+条件-->具体+模糊[处理]
//      2.右键另存为查看文件编码:
//          如果编码是ANSI就可以不用宽字符处理,但是如果是
//          采用Unicode编码进行存储的数据就必须使用宽字符处理
//05数据挖掘流程:
//      1.先进行数据特点分析,再进行数据挖掘-->数据分析
//      2.为每行数据创建一个结构体,封装数据,以便于处理:
//          信息描述+信息封装
//      3.按照空格进行扫描-->不行-->字符串预先处理
//          读取到前面的有效数据就行了-->非完整数据
//      4.额外的数据处理-->处理掉垃圾字符
//          随机选行20~30行的数据特征分析
//      5.需要跳过表头文件信息
//      6.数据不完整-->数据不整齐-->提高数据挖掘难度
//      7.某些数据遇到空格的时候,无需进行数据扫描
//      8.数据如果很长的话,使用空格,逗号也无法挖掘
//          再想办法-->网上下载数据-->数据库备份的方式
//          问题:网络中断-->数据写不完整-->处理麻烦
//06更好的进行数据处理:
//      需要进行数据调整-->DangDangWang
//      当当网数据处理-->CSND数据整齐,读多少都没有问题
//      当当网数据-->又的有空格,有的没有空格
//      -->没有最简单的方法-->可以使用字符串进行处理
//      但是很累
//07sscanf();sprintf();都有这样一个特点:
//      投机取巧的场合
//08fprintf();将数据整理好之后,在内存里面写入进去很方便
//      但是这个时候要进行读取的时候,多一个少一个都不好处理
//      所以不能使用sscanf();进行处理-->它只能处理最标准的数据
//09每一行的格式一样就很容易处理

程序片段(06):List.h+List.c+Main.c
内容概要:CSDN密码库生成

///List.h
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<stdlib.h>
#include <string.h>

//密码字典结构体
typedef struct passinfo
{
    char password[20];
    int ci;
    struct passinfo *pNext;
}INFO, *PINFO;

//尾部插入
PINFO addback(PINFO phead, char password[20]);
//排序-->密码排序|次数排序
PINFO sortbyci(PINFO phead);
PINFO sortbypass(PINFO phead);
//显示
PINFO show(PINFO phead);
//存在判断-->内部操作-->没有的情况进行尾插,存在的情况进行+1
int isin(PINFO phead, char password[20]);
//写入文件
void writetofile(PINFO phead, char path[100]);


//分析一:
//形成链表结构的步骤:
//1.遍历
//2.尾部插入
//3.排序[最后排序]
//      链表的快排-->冒泡排序

//分析二:
//插入分析:
//1.尾部插入
//2.Password
//3.次数[尾部插入的次数一般都为1,必然是1]
///List.c
#include "List.h"

PINFO addBack(PINFO phead, char password[20])//尾部插入
{
    //(1).开辟内存
    PINFO pnew = calloc(1, sizeof(INFO));
    //(2).数据填充
    strcpy(pnew->password, password);//拷贝密码
    pnew->ci = 1;
    pnew->pNext = NULL;
    //(3).组织链表
    if (phead==NULL)
    {
        phead = pnew;
    }
    else
    {//1).链表节点的插入顺序:头部插入,因为与现有函数没有关系
        //2).采用同头插法isin&writetofile&sort...-->头插法
        //      头插法效率更高一些,因为减少遍历到尾部的操作
        //3).链表操作流程:
        //      (1.新节点记录"头结点"首地址
        //      (2.让"头指针"记录新节点"首地址"
        pnew->pNext = phead;
        phead = pnew;//头插法
    }
    return phead;
}

PINFO show(PINFO phead)//显示
{
    if (phead==NULL)
    {
        return;
    }
    else
    {
        printf("%s,%d\n", phead->password, phead->ci);
        show(phead->pNext);//递归:顺序显示
    }
    return phead;
}

int isin(PINFO phead, char password[20])//判断存在与否
{
    PINFO p = phead;
    while (p != NULL)
    {
        if (strcmp(p->password, password) == 0)
        {
            p->ci += 1;
            return 1;//存在
        }
        p = p->pNext;
    }
    return 0;//不在链表内部
}

PINFO sortbyci(PINFO phead)//排序
{
    //(1)代码量最少的排序方式:冒泡
    for (PINFO p1 = phead; p1 != NULL; p1 = p1->pNext)
    {//(2)数组冒泡排序法
        for (PINFO p2 = phead; p2 != NULL; p2 = p2->pNext)
        {//(3)对比密码次数
            if (p2->pNext!=NULL)
            {//(4)数据访问安全检查,防止使用空指针
                if (p2->ci<p2->pNext->ci)
                {//(5)对调:密码+次数-->交换内容方便-->交换节点就如同链表逆转
                    int citemp = p2->ci;
                    p2->ci = p2->pNext->ci;
                    p2->pNext->ci = citemp;

                    char passtemp[100];//(6)交换数据
                    strcpy(passtemp, p2->password);
                    strcpy(p2->password, p1->password);
                    strcpy(p1->password, passtemp);
                }
            }
        }
    }
}
PINFO sortbypass(PINFO phead)
{
    for (PINFO p1 = phead; p1 != NULL; p1 = p1->pNext)
    {
        for (PINFO p2 = phead; p2 != NULL; p2 = p2->pNext)
        {//对比密码
            if (p2->pNext!=NULL)
            {
                if (strcmp(p2->password, p2->pNext->password) < 0);
                {//从小到大
                    int citemp = p2->ci;
                    p2->ci = p2->pNext->ci;
                    p2->pNext->ci = citemp;

                    char passtemp[100];
                    strcpy(passtemp, p2->password);
                    strcpy(p2->password, p1->password);
                    strcpy(p1->password, passtemp);
                }
            }
        }
    }
}
void writetofile(PINFO phead, char path[100])//写入到文件
{
    //(1)既可以按照文本的方式也可以按照二进制的方式
    //      我们便于对数据的查询操作,所以还是采用文本方式
    FILE *pf = fopen(path, "w");
    PINFO p = phead;
    while (p!=NULL)
    {//(2)逐个遍历链表节点结构
        //(3)将字符数据按照规律打印到文本文件当中
        //      注意是否需要进行换行动作
        fprintf(pf, "%s %d\n", p->password, p->ci);//打印到文件
        p = p->pNext;
    }
    fclose(pf);
}
///Main.c
#include "List.h"
#include "Windows.h"

//1.链表头指针最好放到开头位置
PINFO phead = NULL;

void main01()
{                                      
    PINFO phead = NULL;

    //(1)存储常量字符串的时候,实际存储的是指向常量字符串的指针-->假定文件读取
    char *str[10] = { "123","1234","456","789",
    "2345","123","456","789","1234","123" };

    for (int i = 0; i < 10; i++)
    {
        if (isin(phead, str[i]) == 0)
        {
            phead = addback(phead, str[i]);
        }
    }
    show(phead);
    sortbyci(phead);
    printf("\n\n");
    show(phead);
    sortbypass(phead);
    printf("\n\n");
    show(phead);

    writetofile(phead, "D:\\TestData\\x.txt");
    system("D:\\TestData\\x.txt");

    system("pause");
}

//检测数据是否符合fscanf操作标准-->fscanf操作标准数据
int isoktosscanf(char *str)
{
    char *p = strstr(str, "#");
    if (p!=NULL)
    {
        if (strstr(p+1,"#"))
        {
            return 1;
        }
        else
        {
            return 0;
        }
    }
    else
    {
        return 0;
    }
}

//双指针错误删除法
void eatspace(char *str)
{
    int i = 0;
    int j = 0;
    while (str[i] = str[j++] != '\0')
    {//装指针错位法
        if (str[i]!=' ')
        {
            i++;
        }
    }
}

void fileload()
{
    FILE *pf = fopen("D:\\TestData\\x.txt", "r");
    //更好的进行提示
    printf("\n开始读取!");
    while (!feof(pf))
    {
        /*char str[100] = { 0 };
        fgets(str, 99, pf);
        if (isoktosscanf(str) == 0)
        {
            printf("%s\n    ,str");
        }*///(1)数据检测完毕,没有问题

        //(2)需要生成两个文件,生成不同特点的密码库
        //(3)先扫描出数据,构建结构体,再写入到文件当中
        //char password[100];
        (4)排列的时候,尽量按照ASCII码值进行集合处理
        (5)数据读取的时候需要进行排除的部分必须有读过操作,'\n'也需要读过,因为只有你读过了,才能够读取到下一个部位,而fscanf经常都有缓冲区截断特点,而我们这里是读取文件
        fscanf(pf, "%*[0-9A-Za-z_]%*[# ]%[^# ]%#[# ]%*[0-9A-Za-z.@_-]%*[^0-9A-Za-z]", password);//(6)读取到任意一个字符就终止,fscanf();是按行进行读取的
        //fscanf(pf, "%*[0-9A-Za-z_]%*[# ]%[^# ]%#[# ]%*[^#.@-_$;+%,]%*[^0-9A-Za-z]", password);//放款读取范围
        //if (isin(phead, password) == 0)
        //{
        //  phead = addback(phead, password);
        //}
        puts(password);//(7)这里可以查询到哪些字符有问题
        Sleep(2000);//(8)验证读取状态流程
        //(9)这里使用fscanf();不靠谱,因为里面的数据都是未知的
        //  即使今天正常,以后进行使用还是会出一些问题

        //(10)换用靠谱一点儿的方式:直接将密码提取出来
        //  找到两个#号位置,并且将空格给删除掉->问题分析
        char str[100] = { 0 };
        char password[100] = { 0 };
        fgets(str, 99, pf);
        char *p1 = strstr(str, "#");
        char *p2 = strstr(p1 + 1, "#");
        *p1 = '\0';
        *p2 = '\0';
        strcpy(password, p1 + 1);//拷贝字符串
        eatspace(password);
        if (isin(phead,password)==0)
        {
            phead = addback(phead, password);
        }
    }

    printf("\n结束读取!");
    fclose(pf);

    printf("\n开始次排序!");
    sortbyci(phead);
    writetofile(phead, "D:\\TestData\\ci.txt");
    printf("\n结束次排序!");

    printf("\n开始密码排序!");  
    sortbypass(phead);
    writetofile(phead, "D:\\TestData\\pass.txt");
    printf("\n结束密码排序!");
}

void main()
{
    //(1)CSDN数据比较整齐-->所以可以使用fscanf-->
    //      而且必须要出现两个#号的情况之下才能将数据扫描出来
    //      所以需要在编写一个函数,判定每一行是否符合条件
    //      否则会出现一些问题-->fscanf需要数据规律整齐
    //
    fileload();

    system("pause");
}



//八.CSDN密码库生成:
//01.压力地方:CSDN账号&密码数据库
//      1.用户名+密码=破解领导密码-->找到上司的蛛丝马迹-->然后进行密码的有效分析
//      2.暴力破解(穷举)法-->将密码出现概率最高的放在前面进行破解
//      3.密码出现次数多的放在最前面的一块儿
//02.完成任务:
//      1.读取一个文件,生成一个密码序列概率数据库
//      2.出现次数多余出现次数少的-->程序员一个名字用的比较多:娟儿
//      3.1234567这样的密码是使用的最多的
//03.密码字典:
//      1.形成密码字典
//      2.密码概率分析
//04.密码数据库编制流程:
//      1.CSDN账号密码文本数据
//      2.分析有效信息:账号&密码&邮箱
//          密码学统计方式
//      3.用户信息结构体数组:
//          单个结构体:密码Pass&次数Count-->密码概率生成密码字典
//          密码概率字典-->找出密码出现次数最多的,出现次数第二多的,第三多的
//05.CSDN演示-->所有数据提取分析密码-->概率论分析
//      淘宝生意-->专业破解邮箱1500元-->破解概率80%
//      原理:密码概率论-->最蠢的方式就是暴力穷举法-->
//          提升密码破解概率:密码字典数据库
//06.密码字典分析:
//      1.密码Pass&次数Count
//          struct{
//              int pass;
//              int ci;
//          }
//      2.存储方式:
//          链表&数组-->增加密码-->使用链表出串联
//          链表特点:
//              (1)便于多次的密码数据库增加,防止使用数组
//                  realloc消耗资源
//              (2)建立链表关系,建立串联体系
//                  查询密码Pass,判定密码库链表结构当中是否
//                  存在该密码,如果存在, 那么概率次数+1,如果不
//                  链表尾部建立结构体节点,设置初始化概率次数为1
//              (3)链式存储的优越性
//                  链表排序-->密码字典写入到文件-->从头遍历
//                  到尾部进行密码破解
//      3.破解WiFi密码:原理就是CMD
//          小型项目:密码破解字典
//07.如果使用数组最大的弊端在哪里?
//      提取数据的时候比较痛苦-->这里链表的排序时机?
//      温固链表结构:
//08.如何定义链表结构体?如何解决内存?
//      链表数据结构测试完毕
//09.生成密码库:
//      1.链表结构经过测试之后变得比较稳定
//      2.现在需要写入文件
//      3.写入文件之后,需要进行查询的时候,再将其调出来
//          进行数据查询
//10.功能测试
//      1.一步一步的进行代码微调,做到最优化
//      2.先局部,再全局
//11.这里边儿还是数据存在一定的问题:
//      问题特征:中间多了一个-号
//      确定问题所在-->根据数据进行动态调整
//      往往程序不会出问题-->但是数据会有问题-->太坑了
//12.处理大数据的特点:
//      (1)内存不断增加:链表数据结构
//      (2)少用系统函数,自己进行数据处理
//          除非数据是自己收集的,完全是由规律的数据
//      (3)重复密码就不会到达175M
//      (4)冒泡排序的效率不是很高-->需要快排
//          链表操作同样慢-->密码库的生成 

程序片段(07):01.缓冲区.c+02.文本文件读写.c+03.二进制文件读写.c
内容概要:非缓冲区编程

///01.缓冲区.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>  
#include <stdlib.h>

//fgetc();&fputc();
//fgets();&fputs();
//fgetwc();&fputwc();
//fgetws();&fputws();
//fread();&fwrite();
//这些函数都是缓冲区编程,也就不能实时进行操作
//但是某些数据的操作要求比较高,不能够使用这种方式
//比如银行获取数据,中间断电的情况
void main01()
{
    (1)不存在的文件,采用"w"模式就会自动创建
    //FILE *pf = fopen("D:\\TestData\\5.txt", "w");

    //fputs("hello china", pf);

    //fclose(pf);//(2)这里如果不使用fclose();数据也就不会真正
    的被写入到文件当中[只是创建了文件,但是没有数据内容]
    理论上的特点-->但是会出现偶然情况

    FILE *pf = fopen("D:\\TestData\\6.txt", "w");
    fputs("hello china", pf);//(3)这里没有自动写入数据,所以这个程序只要以外崩溃了之后,数据就会丢失
    system("pause");//(4)执行到这个位置,数据不会别写入到文件当中

    fclose(pf);//(5)自动关闭的情况下,会自动的清空缓冲区数据内容
    //如果手动关闭的情况下,会将数据写入到磁盘当中
    //除非是数据不断的读取过程当中,当缓冲区当中的内容
    //充满了的情况下回自动的写入到磁盘当中

    system("pause");
}

void main()
{
    FILE *pf = fopen("D:\\TestData\\10.txt", "w+");//w模式不可写
    fputs("hello world", pf);//(1)没有真正的写入操作,数据并没有生效
    //rewind(pf);//(2)控制文件指针的位置
    fflush(pf);//(3)生效:刷新动作操作的是缓冲区内容-->然后再读取缓冲区内容,就会出现异常信息
    //char ch = fgetc(pf);(4)这里如果需要表现异常,需要使用int进行接收
    int ch = fgetc(pf);//-->避免数据读取错误[表示异常]
    //写入文件的时候,按照读取模式就会发生操作异常
    if (ch==EOF)//(4)结束+意外结尾[异常情况]
    {                                                                      
        if (feof(pf))
        {//(5)这里不会出现异常,因为还没有达到真正的结尾
            //文件指针依然指向缓冲区的末尾,而非文件的末尾
            //也就是文件的末尾还没有生成真正的结尾标识
            printf("end");
            clear(pf);//(6)重置文件流,重置之后,使用ferror();判断就不会有现象
        }                          
        if (ferror(pf))
        {//(7)ferror();-->0:正常&1:异常
            printf("ferror");
        }
    }

    //测试文件流的重置状态
    //ch = fgetc(pf);
    //putchar(ch);//可能读取到空格数据

    printf("\n");
    while (!feof(pf))
    {
        ch = fgetc(pf);
        putchar(ch);
    }

    /*if (ferror(pf))
    {
        printf("ferror");
    }
    fclose(pf);*/

    system("pause");
}



//九.缓冲区介绍:
//01.非缓冲编程模式:另外一种文件操作
//      1.实时操作
//      2.非缓冲编程模式
//02.非缓冲编程与缓冲编程的区别:
//      fputs();不是实时写入数据的,因为在它操作的过程中
//          是具有一个缓冲区操作过程的
//  03.操作什么样的设备可以使用缓冲区,什么样的数据不可以使用缓冲区?
//      1.磁盘&显示器&键盘是不能缓冲的
//      2.例子:键盘+显示器+磁盘 
//04.清除缓冲区编程当中出现错误的情况:
//      缓冲区数据未能成功的刷入进文件当中
//05.当缓冲区当中的内容被清除之后,再使用fgets();进行
//      读取就会读取到EOF这个结果EOF=fgets();
//06.EOF有两种含义:
//      正常结束+意外异常
//07.fflush();
//      清空缓冲区内容,然后再读取缓冲区内容就是EOF
//          也就是-1
//08.fclear();重置文件流状态
//      相当于退回到上一个字符
//09.在缓冲文件编程过程当中,要让数据及时生效:
//      需要使用到fflush();&fclose();
//10.写入的情况之下不能够进行读取
//11.文件流:
//      1.对于异常来说,clearerr();相当于重置文件流的作用
//      2.对于这文件来说,相当于文件指针不再前进
//          文件指针不再前进&重置文件流状态
//12.缓冲区编程特点:
//      1.非实时操作
//      2.不是直接操作文件
//      3.它需要依赖于数据的实时输入
///02.文本文件读写.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>  
#include <stdlib.h>
#include <string.h> 
#include <io.h>
#include <fcntl.h>
#include <sys/stat.h>

char path[128] = "D:\\TestData\\xh-2.txt";
char newpath[128] = "D:\\TestData\\xh-2cpy.txt";

void main01()
{
    //(1)打开文件-->记得关闭
    int fhdr = _open(path, O_RDONLY);
    int fhdw = _open(newpath, O_CREAT | O_WRONLY);
    if (fhdr==-1||fhdw==-1)
    {
        return -1;//操作失败
    }
    else
    {
        //(2)如何判断IO读写的文件结尾?
        while (!_eof(fhdr))
        {//(3)实时操作文件
            char str[256] = { 0 };//(4)_read();返回读取到的字符个数//读取
            int length=_read(fhdr, str, 256);
            _write(fhdw, str, length);//(5)写入的时候长度使用length
        }
        _close(fhdr);//(6)防止关闭两次,但是这里虽然报出异常,但是由于文件是实时写入的,所以文件当中的数据依然存在
        _close(fhdw);
    }

    system("pause");
}

void main()
{
    int fhdr = _open("D:\\TestData\\KaiFang.txt", O_RDONLY);
    if (fhdr==-1)
    {
        return -1;
    }
    else
    {
        while (!_eof(fhdr))
        {//(1)保证数据足够长
            char str[1024] = { 0 };
            int length = _read(fhdr, str, 1024);//(2)_read();有一个弊端:那就是容易读取数据错位-->控制长度-->数据处理不够精准
            char *p = strstr(str, "曾彬");
            if (p)//(3)注意
            {
                printf("%s", str);
            }
        }
        _close(fhdr);
    }

    system("pause");
}



//01.文本文件读写:
//      1.既读又写
//      2.同时操作
//      3.文本文件
//02.了解两个因素:
//      1.文件拷贝:
//      2.大数据:
//03.实时写入的同时
//      1.需要实时刷新
//      2.实时写入的-->但是显示:需要刷新操纵-->显示刷频
//04.人人网:
//      1.CSDN&2011年数据-->理论毕业-->信用卡
//      2.性别区分
//05.文件不能关闭两次-->文件数据是实时写入的
//06.直接在硬盘里面进行数据的查询操作
//07.非缓冲区模式编程的缺点:
//      1.不能够判断'\n'进行读一个写一个的操作-->弊端
//      2.开放数据不能使用这种方式进行读取
//      3.IO操作只有_read();这么一个读取函数
//08.解决非缓冲区模式缺点的方式:
//      1.双指针:先记录开始,再记录长度
//      2.需要自己实现fgets();功能
//09.IO操作读取模式函数定义:
//      1._filelength();文件长度
//      2._findfirst32();查找第一个文件
//      3._next32();查找下一个
//      4._lseek();移动文件指针的作用
//10.大数据处理编程模式之
//      非缓冲区模式编程-->面试中间不会为-->但是在实际
//      编程经常使用-->随时改变对文件的操作
//      write();写入
//      tell();
//      setmode();
//11.进行关键字查询的时候
//      1.需要切换文档
//      2.提取首行
//          _tell();==ftell();
//      3.弊端:没有fgets():自己实现
//12.瞬间查询一个关键字:
//      需要建立这样一个索引:非缓冲区模式编程技巧
//          前面地址-->后面长度
///03.二进制文件读写
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <io.h>
#include <fcntl.h>
#include<sys/stat.h>

//二进制写入技巧
struct info
{
    char name[100];
    double db;
};

void main01()
{
    //(1)结构体-->写进文本
    struct info infos[8] = { {"zengbin1",9876.5},{"zengbin2",8876.5},
    {"zengbinreal",18876.5},{"zengbin4",18876.5 } ,{"zengbinchangesex",8888876.5},
    {"zengbin5",2876.5},{"zengbin6",388876.5},"zengbin38",238876.5 };

    //(2)单个结构体的大小?
    //printf("\n%d", sizeof(struct info));112*8

    //(3)如何将结构体写入文件?-->注意操作模式
    //创建-->二进制-->只写
    int fhdw = _open("D:\\TestData\\zeng.bin", O_CREAT | O_BINARY | O_WRONLY);
    if (fhdw=-1)
    {
        return;
    }
    else
    {
        //(4)注意大小的算法区别:区分栈内存还是堆内存?
        _write(fhdw, infos, sizeof(infos));
        _close(fhdw);
    }

    system("pause");
}

void main02()
{
    //(1)二进制文件-->栈内存存储
    struct info infos[8] = { 0 };
    int fhdr = _open("D:\\TestData\\zeng.bin", O_BINARY | O_RDONLY); 
    if (fhdr)
    {
        return;
    }
    else
    {
        _read(fhdr, infos, sizeof(infos));
        _close(fhdr);
    }
    for (int i = 0; i < 8; i++)
    {
        printf("娃娃名称%s 娃娃价格%f\n", infos[i].name, infos[i].db);
    }

    system("pause");
}

void main()
{
    struct info info1 = { 0 };

    int fhdr = _open("D:\\TestData\\zeng.bin", O_BINARY | O_RDONLY);
    if (fhdr==-1)
    {
        return -1;
    }
    else
    {
        while (1)
        {
            int num;
            scanf("%d", &num);
            _lseek(fhdr, sizeof(info1)*(num - 1), SEEK_SET);
            _read(fhdr, &info1, sizeof(info1));
            printf("娃娃名称%s  娃娃价格%f\n", info1.name, info1.db);
        }
        _close(fhdr);
    }

    system("pause");
}



//十一. 非缓冲区初级二进制文件编程:
//01.二进制文件的非缓冲区模式编程
//02.二进制文件的随机读写操作:
//      文件的二分查找法和合并:合并-->二分查找法

程序片段(08):IO.c
内容概要:IO

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#include <fcntl.h>//控制文件打开模式
#include <sys/stat.h>//系统底层操作

//银行数据安全要求严格
//键盘,鼠标,显卡设备

void main01()
{
    //(1)缓冲区编程模式,在缓冲区未满状态下,无法自动写入文件
    char str[256] = { 0 };
    scanf("%s", str);
    //(2)非缓冲区编程模式:-->O_WRONLY[未提示状态]-->#include <sys/stag.h>
    //(3)这里是IO实时操作,实时生效-->这里可读可写-->创建并写入[如果没有就创建,否则就直接写入,这里是每次创建]
    int fhd = _open("D:\\TestData\\Mem.txt", O_WRONLY | O_CREAT);
    if (fhd = -1)
    {
        printf("打不开!");
    }
    else
    {//(4)IO写入操作-->sizeof(str)+strlen(str)
     //sizeof();写入的是整个类型长度
     //strlen();是只写入字符串长度
        _write(fhd, str, sizeof(str));//(5)即时生效
        _close(fhd);//(6)关闭文件句柄:打开文件之后关闭文件
                    //这里不是操作内存缓冲区,而是文件
    }


    system("pause");
}

void main02()
{
    char str[256] = { 0 };
    //(1)_open();是打开指定路径下的文件
    //(2)只读:O_RDONLY|文本:O_TEXT|表格:O_EXCEL
    int fhd = _open("D:\\TestData\\Mem.txt", (O_RDWR | O_TEXT);
    if (fhd == -1)
    {//(3)fhd==-1:表明文件打不开
        printf("打不开!");
    }
    else
    {
        _read(fhd, str, 256);
        puts(str);
        _close(fhd);//关闭文件
    }

    system("pause");
}


//十.非缓冲区模式初级文本编程:
//01.实时输入:IO操作-->流的操作
//      1.fgets();fputs();本质就是操作内存,通过操作系统实现
//          文件的读写[内存缓冲区-->缓冲区编程]
//      2.IO:Input&Output
//  02.非缓冲区文件编程模式
//      1.#include <io.h>-->IO操作
//         #include <fcntl.h>-->文件打开模式
//         #include <sys/stat>-->sys驱动/stst状态
//      2.
//03.O_WRONLY定义内容:
//#define O_RDONLY     _O_RDONLY
//      只读
//#define O_WRONLY     _O_WRONLY
//      只写
//#define O_RDWR       _O_RDWR
//      读写
//#define O_APPEND     _O_APPEND
//      增加
//#define O_CREAT      _O_CREAT
//      创建
//#define O_TRUNC      _O_TRUNC
//#define O_EXCL       _O_EXCL
//#define O_TEXT       _O_TEXT
//      文本
//#define O_BINARY     _O_BINARY
//      二进制
//#define O_RAW        _O_BINARY
//#define O_TEMPORARY  _O_TEMPORARY
//      临时
//#define O_NOINHERIT  _O_NOINHERIT
//#define O_SEQUENTIAL _O_SEQUENTIAL
//#define O_RANDOM     _O_RANDOM
//      随机读写
//04.文档信息-->使用查询-->基础使用
//      IO实时操作特性-->IO操作文档[查询]
//05.实时生效,即刻生效的模式
//06.非缓冲模式编程:
//      1.是用于银行,对于数据安全严格的
//      2.想键盘,鼠标,显卡设备都需要对数据的实时操作
//      3.这种操作是直接操作系统底层,所以效率很高
//07.非缓冲区编程的高级应用:
//       既读又写操作
psins.cpp是一段C++代码,它主要实现了一种称为“粒子群算法”的优化算法。该算法最初由Eberhart和Kennedy于1995年提出,旨在解决优化问题,尤其是寻找复杂非线性问题的全局最优解。本次详解将从算法原理、程序结构和实现细节三个方面来阐述psins.cpp。 首先,psins.cpp实现的算法原理是粒子群算法。这是一种模拟群体行为的启发式优化算法,它通过模拟鸟群或鱼群等自然群体中的行为方式,来寻找全局最优解。在算法执行过程中,粒子数量和位置表示待解优化问题的解空间,每个粒子都根据自己在解空间中的位置和速度,以及其与周围粒子的交互信息,来更新自己的位置和速度。这样,粒子群可以在解空间中搜索最优解,并逐渐收敛于全局最优解。 其次,psins.cpp的程序结构主要包括初始化、更新粒子位置和速度、计算适应度函数和更新全局最优解四个阶段。在初始化阶段,算法需要设置粒子数量、搜索范围、速度范围、惯性权重等参数,以及随机生成初始粒子位置和速度。在更新粒子位置和速度阶段,粒子会根据自己的位置、速度、惯性权重、个体经验和全局经验等因素,更新自己的位置和速度。在计算适应度函数阶段,算法将根据当前粒子位置计算适应度函数值,用来评价当前解是否优秀。在更新全局最优解阶段,算法将比较所有粒子的适应度函数值,选出全局最优解并更新。 最后,psins.cpp还包括一些实现细节,如使用矩阵和随机数生成器等库函数、使用静态变量和宏定义等优化代码结构、使用C++面向对象风格等。这些细节可以提高代码的可读性和可维护性,同时也确保程序执行效率和数值精度等方面的性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值