程序片段: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 [email protected] xijaxi16ytja6t7ibcrj]进行处理
//(1).匿名代码块儿的使用:划分变量的作用域
int i = 0;
char email[100] = "[email protected]";
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 [email protected] 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# [email protected]\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 # [email protected]
// 扫描提取数据:
//03.scanf的几种表现形式:
// scanf:只是用于键盘输入,起不了核心作用
// 具备缓冲区问题,需要实时清空缓冲区进行处理
// sscanf:字符串扫描
// fscanf:文件扫描
//04.解释:连续执行数据操作进行解析
// 举例:%[0-9A-Za-z] %*[^0-9A-Za-z]
// 1.读取一个集合,遇到不是数字或者大小写字母就跳出
// 2.读取所有的非数字字母字符
// 3.类似于正则表达式
//05.常用的两种数据扫描方式:
//五.fscanfsscanf扫描数据:
//01.拼装组合数据
//02.数据处理流程:
// 分析:zdg # 12344321 # [email protected]
// 数字字母 空格采用*进行跳过
// 跳过原理:先进行读取,再进行废弃
// 注意: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.非缓冲区编程的高级应用:
// 既读又写操作