1 第 8 第 第第第第第第
Jan 02, 2016
1
第 8 章 高级编程技术
2
本章目标
掌握 MATLAB 文件处理方法理解 MATLAB 应用程序接口的原理了解结构和元胞这两种复杂数据类型了解面向对象编程的基本概念
3
主要内容
8.1 文件8.2 应用程序接口
4
8.1 文件
文件可分为两类: 文本文件
由字符和与字符的显示格式有关的控制符构成常见扩展名:“ TXT” 、“ BAT” 、“ HTM”
二进制文件 二进制文件为非文本文件常见扩展名:“ COM” 、“ EXE” 、“ BMP” 、“ WAV”
5
MATLAB 中基本的低级文件 I/O 指令:
1 .打开和关闭文件 fopen 、 fclose
2 .格式读写 fprintf 、 fscanf 、 fgetl 、 fgets
3 .非格式读写 fread 、 fwrite
4 .文件定位和状态 feof 、 fseek 、 ftell 、 ferror 、 frewind
6
8.1.1 文件的打开与关闭
1 . fopen 函数 fid = fopen(filename , permission) [fid,message]=fopen(filename,permssion) [filename,permission,machineformat]=fopen(fid) fid =fopen('all')
2 . fclose 函数 status=fclose(fid) status=fclose('all')
例:打开一个名为 std.dat 的数据文件并进行读操作,命令为: fid = fopen('my.txt','r')
7
8.1.2 格式化数据的读写
fprintf 函数 count=fprintf(fid,format , A ...)
fscanf 函数 [A, count]=fscanf(fid, format, size)
8
例 8-1
计算当 x=[0 1] 时 f(x)=ex 的值,并将结果写入到文件 my.txt 中。
程序 x=0:0.1:1;
y=[x;exp(x)]; %y 有两行数据fid=fopen('my.txt','w');
fprintf(fid,'%6.2f %12.8f\n',y);
fclose(fid);
9
例 8-2
从上例中生成的文件 my.txt 中读取数据,并将结果输出到屏幕。程序 fid = fopen('my.txt','r');
[a,count] = fscanf(fid,'%f %f',[2 inf]); fprintf(1,'%f %f\n',a);
fclose(fid);
输出 同例 8-1 文件中的数据格式。
10
8.1.3 文件定位和文件状态
1 . feof 函数:检测文件是否已经结束 status=feof(fid)
2 . ferror 函数:用于查询文件的输入、输出错误信息 msg=ferror(fid)
3 . frewind 函数:使位置指针重新返回文件的开头 frewind(fid)
4 . fseek 函数:设置文件的位置指针 status=fseek(fid, offset, origin)
5 . ftell 函数:用于查询当前文件指针的位置 position=ftell(fid);
11
例 8-3 输出文件的大小。
程序 fid=fopen('my.txt','r');fseek(fid,0,'eof');x=ftell(fid);fprintf(1,'File Size=%d\n',x);frewind(fid);x=ftell(fid);fprintf(1,'File Position =%d\n',x);fclose(fid);
输出 File Size = 231File Position = 0
12
8.1.4 按行读取数据
1 . fgetl 函数:按行从文件中读取数据,但不读取换行符。
line=fgetl(fid)
2 . fgets 函数:用于从文件中读取行、保留换行符并把行作为字符串返回。
( 1 ) line=fgets(fid) ( 2 ) line=fgets(fid,nchar)
13
例 8-4
编写一个程序,用于读取例 8-1 生成的数据。程序 fid=fopen('my.txt','r');while ~feof(fid)% 在文件没有结束时按行读取数据 s=fgets(fid); fprintf(1,'%s',s);endfclose(fid);输出 同例 8-1 文件中的数据格式。
14
8.1.5 二进制数据文件的读写
fwrite 函数:用于向一个文件写入二进制数据 count=fwrite(fid, A, precision) 。
fread 函数:用于从文件中读二进制数据 [A,count]=fread(fid, size, precision)
注意:使用函数 fread() 和 fwrite() 读写文件时 , 必须以二进制方式打开文件
15
例 8-5
将 5 行 5 列“魔方阵”存入二进制文件中。
程序fid=fopen('my.dat','w');
a=magic(5);
fwrite(fid,a,'long');
fclose(fid);
16
例 8-6
从二进制文件中读取“魔方阵”。程序fid=fopen('my.dat','r');
[A,count]=fread(fid, [5, inf], 'long');
fclose(fid);
A
17
8.1.6 图像、声音文件的读写
1 . imread 函数:从文件中读入图像 A = imread(filename,fmt) [A, map] = imread(filename,fmt)
2 . image 函数:显示图像 image(A)
3 . imwrite 函数:将图像写入文件 imwrite(A, filename, fmt) imwrite(A, map, filename, fmt)
18
例 8-7
显示一幅真彩 (RGB) 图像。程序[x,map]=imread('C:\MATLAB7\toolbox\matlab\demos\street1.jpg');
image(x);
19
例 8-8 将图像写入文件程序[x,map]=imread('C:\MATLAB7\toolbox\matlab\demos\street1.jpg');imwrite(x,'my.bmp'); % 将图像保存为真彩色的 bmp[x,map]=imread('my.bmp');image(x);
20
8.1.6 图像、声音文件的读写
4 . imfinfo 函数:查询图像文件信息 innfo = imflnfo(filename)
5 . wavread 函数:用于读取扩展名为“ .wav” 的声音文件
y=wavread(file) [y, fs, nbits]=wavread(file)
6 . wavwrite 函数:用于将数据写入到扩展名为“ wav” 的声音文件中
wavwrite(y, fs, nbits, wavefile) 7 . wavplay 函数:利用 windows 音频输出设备播放声音
wavplay(y,fs)
21
例 8-9
读取一个音频数据文件,以不同频率播放,并显示声音波形。程序:y=wavread('C:\MATLAB7\toolbox\simulink\simdemos\simgeneral\toilet.wav')
plot(y);
wavplay(y);
wavplay(y,11025);
wavplay(y,44100);
22
8.2 应用程序接口
MATLAB 的外部接口应用包括如下内容: ( 1 )在 MATLAB 中调用已有的 C/C++ 语言代码; ( 2 )在 C/C++ 语言中调用 MATLAB 的算法; ( 3 )利用 COM 标准进行客户 / 服务器模式开发;
例如在 Visual Basic 程序或者 Microsoft Excel 中调用MATLAB 的算法
( 4 )在 C/C++ 语言中读写 MAT 数据文件。
23
8.2.1 MEX 文件
例 8-10 简单 MEX 文件示例 mexHelloWorld.c 。程序:#include "mex.h"
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
{
mexPrintf("Hello Matlab World!");
}
24
8.2.2 MATLAB 计算引擎
MATLAB 的计算引擎应用就是利用 MATLAB提供的一组接口函数,在用户开发的 C/C++语言应用程序中,通过某种通信机制后台调用MATLAB 应用程序以完成复杂的系统任务。
25
例 8-11
设计一程序,在 C/C++ 语言中调用 mesh 函数来绘制高斯矩阵的曲面。
解题步骤:
26
例 8-11 程序:#include <stdio.h>#include "engine.h"void main(){
Engine *ep;int status = 0;// 打开计算引擎ep = engOpen(NULL);if( ep == (Engine *)NULL ){
printf(" 错误:无法打开 MATLAB 计算引擎 \n" );exit(-1);
}// 执行 MATLAB 指令engEvalString(ep,"mesh(peaks);");getchar();// 关闭 MATLAB 计算引擎status = engClose(ep);if(status != 0){
printf(" 无法正常关闭 MATLAB 计算引擎 \n");exit(-1);
}}
27
8.2.3 基于 COM 组件的接口编程
该方法的主要特点有:( 1 )应用程序完全脱离 MATLAB 工作环境;( 2 ) MATLAB 数学库和工具箱中包括的各种各样的函数,所以降低了编写算法难度;( 3 )由于将算法程序做成了 COM 组件的形式,所以实现了算法的保密。
28
8.2.4 在 C/C++ 语言中读写 MAT 数据文件
支持 C/C++ 语言读写 MAT 文件的函数库有下面几个:1 .打开数据文件── matOpen
MATFile * matOpen(const char *filename,const char *mode)
2 .关闭数据文件── matClose int matClose(MATFile *mfp)
3 .获取变量── matGetVariable mxArray *matGetVariable(MATFile *mfp,const char *name)
4 .写入数据── matPutVariable int matPutVariable(MATFile *mfp, const char *name,const
mxArray *mp)
29
扩展阅读
8.3 结构数组
8.4 元胞数组 8.5 面向对象程序设计
Matlab
5+6i
30
应用举例
例 8-12 在 C/C++ 语言中调用 MATLAB 计算魔方阵,并将结果显示到屏幕。
31
程序代码- 1
#include "engine.h"#include <stdio.h>void main(){
Engine *ep;double *p;mxArray *equation;int i = 0,j=0;int status = 0;// 打开计算引擎ep = engOpen(NULL);if( ep == (Engine *)NULL ){
printf(" 错误:无法打开 MATLAB 计算引擎 \n" );exit(-1);
}
32
程序代码- 2// 执行 MATLAB 指令engEvalString(ep,"A = magic(5);");equation=engGetVariable(ep,"A");p=mxGetPr(equation);printf("\nMATLAB 中计算 magic(5)\n");for(i=0;i<5;i++){
for(j=0;j<5;j++)printf("%8.0lf",*(p+i+j*5));
printf("\n");}// 关闭 MATLAB 计算引擎status = engClose(ep);if(status != 0){
printf(" 无法正常关闭 MATLAB 计算引擎 \n");exit(-1);
}}
33
例 8-13
34
程序代码- 1
#include <stdio.h>#include <string.h>#include "engine.h"void main(){
Engine *ep;int status = 0;ep = engOpen(NULL);// 执行 MATLAB 指令double A[]={2, 3, 4, -1, 1, -1, 3, -5, 1},B[]={5,5,9};double *pa,*pb,*pc;mxArray *x,*y,*z;
35
程序代码- 2
x=mxCreateDoubleMatrix(3,3,mxREAL);y=mxCreateDoubleMatrix(3,1,mxREAL);pa=mxGetPr(x);pb=mxGetPr(y);memcpy(pa,A,9*sizeof(double));memcpy(pb,B,3*sizeof(double));engPutVariable(ep,"A",x);engPutVariable(ep,"B",y);engEvalString(ep,"C=A\\B;");z=engGetVariable(ep,"C");pc=mxGetPr(z);printf("\nAX=B 的结果为: \n");for(int i=0;i<3;i++){
printf("%8.0lf\n",*(pc+i));}status = engClose(ep);
}
36
学好计算机的唯一途径是
你的编程能力与你在计算机上投入的时间成
结 束 语