新买的 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;
}
posted @   xuchaoxin1375  阅读(10)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示