单线程实现检索当当网泄露的1GB用户数据

简介:  新建项目dangdangusersearch 2.编写头文件head.h #ifndef _HEAD_H_ #define _HEAD_H_   #include <stdio.h>    //注意文件操作相关函数的头文件是stdio.h #include<stdlib.h>    //为了

  1. 新建项目dangdangusersearch

2.编写头文件head.h

#ifndef _HEAD_H_

#define _HEAD_H_

 

#include <stdio.h>    //注意文件操作相关函数的头文件是stdio.h

#include<stdlib.h>    //为了使用system函数

#include <string.h>   //字符串操作所用到的头文件

#include<Windows.h>   //使用休眠函数时用到的头文件

#include <crtdbg.h>   //做内存泄露检测所需的头文件

 

//开启内存检测

#define _CRTDBG_MAP_ALLOC

 

/*菜单查看*/

extern void main_view();

 

/*获得文件的字节大小*/

extern int getFileSize(const char *path);

/*加载文件,fPath为传递进去的文件路径*/

extern void loadFile(const char *fPath, const int rowSize);

/*通过关键字查找*/

extern void findStringByKeyword(const char *keyword, const int rowSize);

/*查看文件中有多少行*/

extern int getFileRow(const char *path);

/*释放存放每行直至的数组的内存和每行字符串所占的内存*/

extern void freeMemory(char **pp, const int rowSize);

 

#endif

3.编写main.c

//注意文件操作相关函数的头文件是stdio.h

#include "head.h"

 

/*菜单查看*/

void main_view()

{

    system("cls");

    printf("\n******************当当用户信息查询系统*******************\n");

    printf("\t1.载入数据至内存(-l)\n");

    printf("\t2.查找字符串(-s)\n");

    printf("\t3.释放内存(-f)\n");

    printf("\n*************************0.退出**************************\n");

}

4.编写file.c

#define _CRT_SECURE_NO_WARNINGS

#include "head.h"

 

char **pp = NULL; //存储指针数组的地址

FILE *pf = NULL;  //定义一个文件指针

int flag = 0;     //这个标识符用于判断是否加载完成,0:标识没有加载,1:表示完成加载,2:表示释放释放内存

 

/*获得文件的字节大小*/

int getFileSize(const char *path)

{

    //按照读取的模式打开

    pf = fopen(path, "r");

    if (pf == NULL)

    {

        //代表获取文件失败

        return -1;

    }

    else

    {

        //fseek():Moves thefile pointer to a specified location.

        fseek(pf, 0, SEEK_END);

        //ftell( FILE*stream ):文件开头到当前位置有多少个字节

        int num = ftell(pf);

        fclose(pf);//关闭文件

        return num;

    }

}

 

/*加载文件,fPath为传递进去的文件路径*/

void loadFile(const char *fPath, const int rowSize)

{

    printf("加载文件中,请稍后....");

    //pp里面存储的是每行字符串的地址

    pp = (char **)malloc(sizeof(char *)*rowSize);

    pf = fopen(fPath, "r");

    if (pf == NULL)

    {

        printf("对不起,加载文件失败!");

        return;

    }

    else

    {

        int i;

        for (i = 0; i < rowSize; i++)

        {

            //读取字符串的缓冲区

            char str[275] = { 0 };

            //*fgets( char*string, int n, FILE *stream );

            //从文件中逐行读取字符串

            fgets(str, 275, pf);

            //获取要分配的字符串长度,最后加一是因为'\0'

            int strlength = strlen(str) + 1;

            //分配内存

            char *px = malloc(sizeof(char)*strlength);

            //拷贝字符串

            strcpy(px, str);

            //设定最后一个字符串为'\0'

            px[strlength - 1] = '\0';

            //存储字符串的首地址到指针数组

            pp[i] = px;

        }

    }

    fclose(pf);

    flag = 1;

    printf("载入内存OK\n");

}

 

/*通过关键字查找*/

void findStringByKeyword(const char *keyword, const int rowSize)

{

    if (pp == NULL)

    {

        printf("对不起,您还没有加载文件,请您先加载文件\n");

        return;

    }

    int i;

    for (i = 0; i < rowSize; i++)

    {

        //遍历所有的指针数组的地址,字符串查找

        char *ptemp = strstr(pp[i], keyword);

        if (ptemp != NULL)

        {

            printf("\n%s", pp[i]);//打印字符串

        }

    }

}

 

int getFileRow(const char *path)

{

    //读取的模式打开

    pf = fopen(path, "r");

    if (pf == NULL)

    {

        //代表获取失败

        return -1;

    }

    else

    {

        int i = 0;

        //是否到文件末尾

        while (!feof(pf))

        {

            char str[275];

            fgets(str, 275, pf);//读取一行

            i++;

        }

        fclose(pf);

        return i;

    }

}

 

/*释放存放每行直至的数组的内存和每行字符串所占的内存*/

void freeMemory(char **pp, const int rowSize)

{

    printf("正在释放内存,请稍后!");

    int i;

    for (i = 0; i < rowSize; i++)

    {

        //通过这种方式释放内存的时候较慢,因为是一行行的释放的

        free(pp[i]);

    }

    free(pp);

    flag = 0;

}

5.编写DDSS.c

#define _CRT_SECURE_NO_WARNINGS

#include "head.h"

 

extern int flag;

extern char **pp;

 

/************************************************************************/

/* 当当用户信息查询系统                                                */

/************************************************************************/

int main(int argc, char *argv[])

{

    //文件所在位置

    char *path = "G:\\dangdangwang.txt";

    int fileSize = getFileSize(path);

    //printf("%d字节,%fK,%fM", fileSize, fileSize /1024.0, fileSize / 1024.0 / 1024.0);

    //这个选择菜单是的字符串

    char choice[25];

 

    //获得行号

    int row = getFileRow(path);

    printf("%d\n", row);

 

flag:system("cls");

    main_view();

    if (flag)

    {

        printf("文件加载完毕,可以进行查找了!\n");

    }

    else if (flag == 0)

    {

        printf("文件未加载状态,请您先加载文件!\n");

    }

    while (1)

    {

        printf("输入内容或选择('-v'显示菜单):");

        scanf("%24s", choice);

 

        if (!strcmp(choice, "-v") || !strcmp(choice, "-view")){

            main_view();

        }

        else if (!strcmp(choice, "-l") || !strcmp(choice, "-loadFile"))

        {

            loadFile(path, row);

        }

        else if (!strcmp(choice, "-s") || !strcmp(choice, "-search"))

        {

            while (1)

            {

                char keyword[100] = { 0 };

                printf("\n请输入要查找的字符串,输入-exit将退出查找\n");

                scanf("%s", keyword);

 

                if (strcmp(keyword, "-exit"))

                {

                    findStringByKeyword(keyword, row);

                }

                else

                {

                    break;

                }

            }

        }

        else if (!strcmp(choice, "-f") || !strcmp(choice, "-free"))

        {

            freeMemory(pp, row);

        }

        goto flag;

    }

 

    system("pause");

    return 0;

}

 

 

 

 

将查询到的结果封装到txt文本中

#define _CRT_SECURE_NO_WARNINGS   //关闭安全检查

#include <stdio.h>

#include <stdlib.h>

 

void main()

{

    char *path = "G:\\dangdangwang.txt";

    char *respath = "G:\\1.txt";

 

    FILE *pf;

    FILE *fp;

    pf = fopen(path,"r");//读的模式

    fp = fopen(respath,"w");//写的模式

    if (pf == NULL)

    {

        printf("文件打开失败");

    }

    else

    {

        //文件指针到末尾

        fseek(pf, 0, SEEK_END);

        int num = ftell(pf);

        char  strinfo[200];

        sprintf(strinfo, "\nnum=%d字节,%fK,%fM", num, num / 1024.0, num / 1024.0 / 1024.0);

        fputs(strinfo, fp);//写入文件

        rewind(pf);//回到文件开头

        while (!feof(pf))

        {

            //缓冲区

            char str[200];

            //读取,按照行读取

            fgets(str, 200, pf);

            if (strstr(str,"谭胜") != NULL)  //字符串查找

            {

                fputs(str, fp);//写入文件

                printf("\n%s", str);//打印结果

            }

        }

        fclose(fp);   //关闭文件

        fclose(pf);   //关闭文件

    }

    //打开结果文件

    system(respath);

    system("pause");

}

 

目录
相关文章
|
5月前
|
Java 索引
多线程向设备发送数据
多线程向设备发送数据
85 0
|
5月前
|
数据采集 监控 调度
干货分享“用 多线程 爬取数据”:单线程 + 协程的效率反超 3 倍,这才是 Python 异步的正确打开方式
在 Python 爬虫中,多线程因 GIL 和切换开销效率低下,而协程通过用户态调度实现高并发,大幅提升爬取效率。本文详解协程原理、实战对比多线程性能,并提供最佳实践,助你掌握异步爬虫核心技术。
|
消息中间件 监控 安全
服务Down机了,线程池中的数据如何保证不丢失?
在分布式系统与高并发应用开发中,服务的稳定性和数据的持久性是两个至关重要的考量点。当服务遭遇Down机时,如何确保线程池中处理的数据不丢失,是每一位开发者都需要深入思考的问题。以下,我将从几个关键方面分享如何在这种情况下保障数据的安全与完整性。
298 2
|
消息中间件 监控 Java
线程池关闭时未完成的任务如何保证数据的一致性?
保证线程池关闭时未完成任务的数据一致性需要综合运用多种方法和机制。通过备份与恢复、事务管理、任务状态记录与恢复、数据同步与协调、错误处理与补偿、监控与预警等手段的结合,以及结合具体业务场景进行分析和制定策略,能够最大程度地确保数据的一致性,保障系统的稳定运行和业务的顺利开展。同时,不断地优化和改进这些方法和机制,也是提高系统性能和可靠性的重要途径。
317 62
|
10月前
|
SQL 数据建模 BI
【YashanDB 知识库】用 yasldr 配置 Bulkload 模式作单线程迁移 300G 的业务数据到分布式数据库,迁移任务频繁出错
问题描述 详细版本:YashanDB Server Enterprise Edition Release 23.2.4.100 x86_64 6db1237 影响范围: 离线数据迁移场景,影响业务数据入库。 外场将部分 NewCIS 的报表业务放到分布式数据库,验证 SQL 性能水平。 操作系统环境配置: 125G 内存 32C CPU 2T 的 HDD 磁盘 问题出现的步骤/操作: 1、部署崖山分布式数据库 1mm 1cn 3dn 单线启动 yasldr 数据迁移任务,设置 32 线程的 bulk load 模式 2、观察 yasldr.log 是否出现如下错
|
9月前
|
数据采集 存储 安全
Python爬虫实战:利用短效代理IP爬取京东母婴纸尿裤数据,多线程池并行处理方案详解
本文分享了一套结合青果网络短效代理IP和多线程池技术的电商数据爬取方案,针对京东母婴纸尿裤类目商品信息进行高效采集。通过动态代理IP规避访问限制,利用多线程提升抓取效率,同时确保数据采集的安全性和合法性。方案详细介绍了爬虫开发步骤、网页结构分析及代码实现,适用于大规模电商数据采集场景。
|
10月前
|
缓存 安全 Java
面试中的难题:线程异步执行后如何共享数据?
本文通过一个面试故事,详细讲解了Java中线程内部开启异步操作后如何安全地共享数据。介绍了异步操作的基本概念及常见实现方式(如CompletableFuture、ExecutorService),并重点探讨了volatile关键字、CountDownLatch和CompletableFuture等工具在线程间数据共享中的应用,帮助读者理解线程安全和内存可见性问题。通过这些方法,可以有效解决多线程环境下的数据共享挑战,提升编程效率和代码健壮性。
332 6
|
缓存 安全 Java
使用 Java 内存模型解决多线程中的数据竞争问题
【10月更文挑战第11天】在 Java 多线程编程中,数据竞争是一个常见问题。通过使用 `synchronized` 关键字、`volatile` 关键字、原子类、显式锁、避免共享可变数据、合理设计数据结构、遵循线程安全原则和使用线程池等方法,可以有效解决数据竞争问题,确保程序的正确性和稳定性。
343 57
|
缓存 NoSQL Java
Java高并发实战:利用线程池和Redis实现高效数据入库
Java高并发实战:利用线程池和Redis实现高效数据入库
975 0

热门文章

最新文章