新买的 U盘这么快就中病毒了!
题目描述 なに?!新买的 U盘这么快就中病毒了! 目录下多出很多同名的可执行文件:比如 1.gif 与 1.gif.exe 对应,main.c 于 main.c.exe 对应。 它们都是病毒。但并不是所有可执行文件(扩展名为 .exe 的文件)都是病毒, 比如图中的 problem.exe,并没不存在一个文件名字叫 problem,所以它不是病毒。 我会给你一些文件名列表,你能开发一款“病毒扫描器”帮我识别出哪些是病毒文件吗? 识别方法是: 文件名以“.exe”结尾。 //strlen(input[i]) 在文件名列表中同时还存在去掉“.exe”后同名的文件。 (病毒文件有其源文件) 输入 输入数据有多组。 每组输入的第一行是一个整数 n(0 < n <= 1000),表示接下来会有 n 个文件名。 接下来的 n 行为文件名,每个文件名占一行。 文件名最多 16 个字符,并且中间不包含空格。 如果 n 等于 0,则程序结束。 输出 以字典顺序输出 每一组数据中的病毒文件名。 每个文件名输出一行。 2 a.txt a.txt.exe 2(改组没有病毒文件) a a.txt 10 a.txt b.txt d.txt.exe c.txt d.txt a.txt.exe e.txt f.txt e.txt.exe g.txt 0 (结束的标志) 样例输出 a.txt.exe(第一组的数据) a.txt.exe d.txt.exe e.txt.exe 提示 例子中第二组没有病毒文件。 找出病毒文件后,输出前不要忘了排序。 识别方法是: 文件名以“.exe”结尾。(就是做出判断:(文件名以“.exe”结尾)的模块) //strlen(input[i]),strlen(接受字符串首地址.) 在文件名列表中 同时还存在 去掉“.exe”后同名的文件。 //这个说法可以等价转换为多种角度的命题/要求.(比如正向/间接反向(截/补)) //strcmp() (病毒文件有其源文件) //!改版本处理直接.exe的文件名,当然你可以以它为单个输入排查bug //处理空白:&&不为空(在k处) /* 升序版字符排序. */ #include <stdio.h> #include <string.h> int main() { char input[2000][17] ; char str_exe[2000][17];/* 保存尾缀为.exe的文件 */ char cp_str_exe[2000][17]; /* test */ // printf("test_8\n"); /* 这样写会有个问题,在scanf结束读入后,回车键还残留在缓冲区中,这会使第一个gets()直接被结束掉. gets(input[i]); for (int i = 0; i < n; i++) */ int n;/* 要读入的文件数目 */ /*测试多组数据:这是要注意变量残留,即某些变量要设置在for/while的内部才可以重新的初始化,当然表达式要初始化一个值才行 */ for(;scanf("%d", &n),n != 0;) { int len = 0;/* 文件名字符串的长度 */ int cnt_str_exe = 0;/* 计数str_exe数组中有多少个该类字符串 */ /* 字符串们写入数组input */ for (int i = 0; i < n ; i++) { scanf("%s",input[i]); } /* 从从input数组中筛选出尾缀为.exe,并写入到str_exe数组中 */ int j = 0; //解决数组str_exe空洞. for (int i = 0; i < n; i++) { len = strlen(input[i]);//如果没有该处的迭代,len可能是个庞大的数据,造成数组下标越界,segtment fault. if (strcmp(&input[i][len - 4], ".exe") == 0)//需要随着i变化而迭代的量:len = strlen(input[i]); { //strcpy(str_exe[i],input[i]);//这样写会造成str_exe有空洞 strcpy(str_exe[j++], input[i]); //这里的j能否内嵌? cnt_str_exe += 1; } } // /* may be the files is a virus file. */ // /* 在文件名列表中 同时还存在 去掉“.exe”后同名的文件。deal_file_name */ /* deal_file_name */ int k = 0;/* 防止cp_str_exe空洞 */ for (int i = 0; i < cnt_str_exe; i++) { len = strlen(str_exe[i]); str_exe[i][len - 4] = '\0';/* 字符串截断处理 */ //int k = 0;/* 防止cp_str_exe空洞,但是把它安排在在循环内部其值无法得到保留,应外挪 */ for (int j = 0; j < n + 1; j++) //内嵌循环时要注意更换循环变量和表达式. /* 检查input中是否有对应的源文件(病毒文件去壳) */ if (strcmp(str_exe[i], input[j]) == 0 && *input[j] != NULL) //或strlen(input[i]) != 0; /* //str_exe已经被修改截断只好后期加上.exe */ // printf("This is a virus file:%s.exe\n", str_exe[i]); strcpy(cp_str_exe[k++],str_exe[i]); } // /* int i=0,j=0; // int n = 0; redefined*/ int i = 0; j = 0; char buf[200]; /* 冒泡排序算法 */ for(i = 0;i<k-1;i++) { for(j=0;j<=k-2-i;j++) { /* 如果前者大于后者.交换位置使得最大者尽量靠后 */ if(strcmp(cp_str_exe[j],cp_str_exe[j+1]) > 0) { /* 调用strcpy(),可以使得字符串的排序和赋值项整数那样利索. */ strcpy(buf,cp_str_exe[j]); strcpy(cp_str_exe[j],cp_str_exe[j+1]);/* 是加号 */ strcpy(cp_str_exe[j+1],buf); } } } for(int i = 0 ; i<k;i++) { //printf("out:"); printf("%s.exe\n",cp_str_exe[i]); } } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了