昨天我们上c++课,老师给布置了一道上机作业
然后大家就都疯了
题目是这样的:
设计一个滑动平均滤波器程序,用来处理一组数字信号,用于消除信号中的高频噪声(毛刺)。
信号数据保存在一个2进制的文件中,文件中的数据类型为整型。
数据文件的格式为:第一个整型数据表示当前文件中保存有多少个信号数据,其后为若干整型信号数据。
滑动平均滤波器的数学公式:
要求:程序为命令行运行方式,带2个参数,第一个为N,第二个为数据文件。
第一眼看见这个题目我也是懵的,难点有三
1、啥叫滑动平均滤波器
2、输入数据要保存在2进制文件中
3、带参数命令行运行方式
要解决这个工程,我们要从三方面入手:
1、滑动平均滤波器
说实话我也不太清楚什么叫滑动平均滤波器
网上说法好像比较多,这边根据题意简单解释一下:
假设我们有一个数列xi(1<=i<=m)
以第i个点为中心往左往右各取N/2个值,求这个区间内一个平均值,和xi作比较,若xi较大,则视xi为异常值,将其排除
从左往右平移窗口进行此过滤操作的算法叫滑动平均滤波器
当然这个题意给出的实在不明朗,大家写法不同也情有可原,这个部分也不是我们要讲的重点
2、二进制文件及从中读取数据
下面是对二进制文件的简单介绍
1、计算机文件分为两种:ASCII码文件和二进制文件
2、我们平时见的最多的就是ASCII码文件,其中代表性的是以txt作为扩展名的文本文件
3、二者之间的区别不大,简单来说就是:
如果一个文件中的每个字节的内容都是可以表示成字符的数据,我们就可以称这个文件为文本文件
也就是文本文件可以转化为二进制文件
4、二进制文件的扩展名通常是.bin
如果有人想要了解二进制文件相关其他内容建议百度哦:
https://baike.so.com/doc/6848461-7065887.html
下面就是我的同学们 所有人最关心的问题了:如何从二进制文件中读取数据(这里给出两种方法:C语言中的文件指针和C++的输入流)
1、C语言文件指针法:
定义文件指针:
FILE* tp;//定义一个名为tp的文件指针
声明文件指针指向的文件:
tp.open("data.txt","r");//"r"表示从文本文件中读入
关闭文件指针:
fclose(tp);
从文件中读取单个字符:
char ch=fgetc(tp);
当然scanf也有其相应用法,鉴于我们是从二进制文件中读入,scanf读入很可能出现稀奇古怪的错误,这里并不赘述
啊对,既然是二进制文件,那扩展名应该是bin吧;而且,“r”是指从文本文件中读入,是不是也要改一下呢?
bingo!
tp=open("data.bin","rb");
当然,还有一件好事,就是关于文件名的问题,由于文件名是一个字符串,所以我们可以直接:
char name[]="data.bin";
tp=open(name,"rb");
那么以上就是用文件指针输入所需的全部操作了
2.流输入
流的详细资料比较多,不一一列出
这一次我们只需要用到的是输入流:
#include<fstream>
ifstream tp;
tp.open("data.bin")
char ch=tp.get();
输入流的定向不需要在后面加个"r"或者"rb",相对来讲更加智能化
值得一提的是,输入流里的文件名,也是可以直接用字符串代替的
#include<fstream>
ifstream tp;
char name[]="data.bin";
tp.open(name);
char ch=tp.getc();
好了,那么输入也解决了
值得一提的是:很多包括我在内自作聪明的 人都把输入形式改成二进制了,这个是不用的,二进制文件可以通过直接编辑txt文件,然后重命名修改扩展名变成bin文件
3、命令行参数
以下文字抄自rainbow70626的博客:
每个C语言程序都必须有一个称为main()的函数,作为程序启动的起点。当执行程序时,命令行参数(command-line argument)(由shell逐一解析)通过两个入参提供给main()函数。第一个参数int argc,表示命令行参数的个数。第二个参数char *argv[],是一个指向命令行参数的指针数组,每一参数又都是以空字符(null) 结尾的字符串。第一个字符串,亦即argv[0]指向的,(通常)是该程序的名称。argv中的指针列表以NULL指针结尾(即argv[argc]为NULL)。
简单来说就是:
int main(int argc,char* argv[])
{
```
return 0;
}
具体执行的时候要靠开始菜单中的命令提示符
或者打开相应文件夹在文件地址中输入“cmd”
按照题面来讲,操作过程应该是这个样子: