在编程读取字节文件Employee.dat中的数据时,应选择使用()类型的流对象
A.Reader
B.Input Stream
C.File Output Stream
D.File Input Stream
A.Reader
B.Input Stream
C.File Output Stream
D.File Input Stream
A.从Input Stream类继承
B.不支持Input Stream的有些方法
C.不适合读取字符文件,适合读取字节文件
D.能实现文件的倒序读取
下列叙述中,正确的是
A.Reader是一个读取字符文件的接口
B.Reader是一个读取数据文件的抽象类
C.Reader是一个读取字符文件的抽象类
D.Reader是一个读取字节文件的一般类
例如:
内存中有:AA55H,55AAH,FFAAH
结果为: PP00H,FF00H,FFAAH
部分程序已给出,其中原始数据由过程LOAD从文件INPUT1.DAT中读入SOURCE开始的内存单元中。运算结果要求从 RESULT开始存放, 由过程SAVE保存到文件OUTPUT1.DAT中。
请填空BEGIN和END之间已经给出的源程序使其完整,空白处已经用横线标出,每个空白一般只需一条指令,但采用功能相当的多条指令亦可,或删去BEGIN和END之间原有的代码并自行编程来完成所要求的功能。
对程序必须进行汇编,并与IO.OBJ链接产生可执行文件,最终运行程序产生结果。调试中若发现整个程序中存在错误之处,请加以修改。
[试题程序]
EXTRN LOAD:FAR,SAVE:FAR
N EQU 3
STAC SEGMENT STACK
DB 128 DUP ()
STAC ENDS
DATA SEGMENT
SOURCE DW N DUP()
RESULT DW N DUP(0)
NAME0 DB 'INPUT1.DAT',0
NAME1 DB 'OUTPUT1.DAT',0
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA, SS:STAC
START PROC FAR
PUSH DS
XOR AX,AX
PUSH AX
MOV AX,DATA
MOV DS,AX
LEA DX,SOURCE ;数据区起始地址
LEA SI,NANE0 ;原始数据文件名
MOV CX,N*2 ;字节数
CALL LOAD ;从'INPUT1.DAT'中读取数据
; ********* BEGIN **********
MOV DI,OFFSET RESULT
MOV CX,N
MOV BX,00
PRO: MOV AX, (1)
MOV DX,AX
AND (2) ,DH
(3) AH,AL
MOV (4) ,DL
ADD BX,2
(5)
ADD DI,2
(6)
JNZ PRO
; ******** END ********
LEA DX,RESULT ;结果数据区首址
LEA SI,NAME1 ;结果文件名
NOV CX,N*2 ;结果字节数
CALL SAVE ;保存结果到文件
RET
START ENDP
CODE ENDS
END START
试题要求如下:
请编制程序,其功能是:从20个有符号字节数据中取出负数并计算其绝对值之和(字型),然后存放在指定的内存区中,多余的空间填0。
例如:
内存中有:80H,02H,00H,7CH,7BH,81H……
结果为: 80H,FEH,FDH,05H,00H,00H……
部分程序已给出,其中原始数据由过程LOAD从文件INPUT1.DAT中读入SOURCE开始的内存单元中,运算的结果要求从RESULT开始存放,由过程SAVE保存到文件OUTPUT1.DAT中。补充BEGIN和END之间已给出的源程序使其完整(空白已用横线标出,每行空白一般只需一条指令,但采用功能相当的多条指令亦可),或删除BEGIN和END之间原有的代码并自行编程来完成要求的功能。
对程序进行汇编,并与IO.OBJ链接产生执行文件,最终运行程序产生结果。调试中发现整个程序中存在错误之处,请加以修改。
试题程序:
EXTRN LOAD: FAR, SAVE: FAR
N EQU 20
STAC SEGMENT STACK
DB 256 DUP ()
STAC ENDS
DATA SEGMENT
SOURCE DB N DUP()
RESULT DB N DUP(0)
NAME0 DB 'INPUT1.DAT', 0
NAME1 DB 'OUTPUT1.DAT', 0
DATA ENDS
CODE SEGMENT
ASSUME CS: CODE, DS: DATA, SS: STAC
START PROC FAR
PUSH DS
XOR AX, AX
PUSH AX
MOV AX, DATA
MOV DS, AX
MOV ES, AX
LEA DX, SOURCE ; 数据区起始地址
LEA SI, NAME0 ; 原始数据文件名
MOV CX, N ; 字节数
CALL LOAD ; 从'INPUT1.DAW'中读取数据
**** BEGIN ****
LEA SI, SOURCE
LEA DI, RESULT
MOV DX, 0
MOV CX, N
CLD
CON: LODSB
(1)
JGE (2)
MOV [DI], AL
INC DI
(3)
INC DI
ADD DL, AL
(4)
NEXT: LOOP CON
MOV [DI], DX
ADD DI, 2
MOV CX, 40
SUB CX, DI
MOV AL, (5)
(6)
; **** END ****
LEA DX, RESULT ; 结果数据区首址
有以下程序(提示:程序中fseek(fp-2L*sizeof(int),SEEK_END) ;语句的作用是使位置指针从文件末尾向前移2*sizeof(ing)字节) #include <stdio.h> main() { FILE *fp; int i, a[4]={1,2,3,4},b; fp=fopen("data.dat","wb"); for(i=0;i<4;i++) fwrite(&a[i],sizeof(int),1,fp); fclose(fp); fp=fopen("data.dat","rb"); fseek(fp,-2L*sizeof(int),SEEK_END) ; fread (&b, sizeof (int),1,fp); /*从文件中读取sizeof(int)字节的数据到变量b中*/ fclose(fp); printf("%d\n",B) ; } 执行后输出结果是
A.2
B.1
C.4
D.3
请编制程序PROC1.ASM,其功能是:内存中有一个ASCII字符串(从S0URCE开始存放),试将其中所有连续的回车与换行符(0DH,0AH)置换成单个回车符(0DH)。字符串以00H结尾,长度(包括00H)不超过100个字节。
例如:字符串41H,42H,0DH,0AH,43H,00H
转换为41H,42H,0DH,43H,00H
部分程序已给出,其中原始数据由过程LOAD从文件INPUT1.DAT中读入SOURCE开始的内存单元中。运算结果要求从RESULT开始存放,由过程SAVE保存到文件OUT- PUT1.DAT中。请编写BECIN到END之间的代码。对程序必须进行汇编,并与IO.OBJ连接产生PROC1.EXE执行文件,最终运行程序产生结果(无结果或结果不正确者均不得分)。
部分源程序如下:
EXTRN LOAD:FAR,SAVE:FAR
N EQU 100
STAC SEGMENT STACK
DB 128 DUP ()
STAC ENDS
DATA SEGMENT
SOURCE DB N DUP (0)
RESULT DB N DUP (0)
NAME0 DB 'INPUT1. DAT', 0
NAME1 DB 'OUTPUT1. DAT', 0
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA, SS:STAC
START PROC FAR
PUSH DS
XOR AX, AX
PUSH AX
MOV AX, DATA
MOV DS, AX
LEA DX, SOURCE ; 数据区起始地址
LEA SI, NAME0 ; 原始数据文件名
MOV CX,N ; 字节数
CALL LOAD ; 从"INPUT1.DAT"中读取数据
**** BEGIN ****
***** END *****
LEA DX, RFSULT ; 结果数据区首址
LEA SI, NAME1 ; 结果文件名
MOV CX,N ; 结果字节数
CALL SAVE
RET
START ENDP
CODE ENDS
END START
编程思路:
第一步:分析程序要求的功能。
本程序需要完成以下功能。
(1)据文件INPUT1.DAT中读取100个ASCII码存放在SOURCE开始的内存单元中。
(2)将SOURCE开始的100个字单元中的ASCII码,将0DH后的0AH删除,并将结果存放在RFSULT开始的内存单元中。
(3)将结果存放在OUTPUT1.DAT中。
第二步:用相应的汇编程序来实现其功能。
(1) 数据的读取和存入文件部分的实现,题目中已经给出。
(2) 如果是将数据在原地进行处理,那么每删除一个数据就要将其后面的所有数据向前移动一个位置,如果直接将扫描处理完毕的数据复制到结果地址中,将会节省移动数据的开销;
因为要删除0DH后面的0AH,所以,在扫描数组的过程中除了要了解当前数据元素的内容还要了解前一个数据的内容。解决方法可使用标志单元记录前一个数据是否为 0DH,然后当前数据元素根据标志单元的内容决定当前元素是否复制到结果中;也可在扫描数组的过程中,如果碰到一个0DH,则进入不同的程序段,这个程序段决定是否将当前数据元素复制到结果中。我们的参考答案采用了后一种方法。
例如:
内存中有 0000H,000FH,FFFFH,…
结果为 10H,0CH,00H,…,最后为n
部分程序已给出,其中原始数据由过程LOAD从文件INPUT1.DAT中读入SOURCE开始的内存单元中。运算结果要求从RESULT开始存放,由过程SAVE保存到文件OUTPUT1.DAT中。
填空BEGIN和END之间已给出的源程序使其完整(空白已用横线标出,每行空白一般只需一条指令,但采用功能相当的多条指令亦可),或删除BEGIN和END之间原有的代码并自行编程来完成要求的功能。
对程序必须进行汇编,并与IO.OBJ链接产生PROG1.EXE执行文件,最终运行程序产生结果 (无结果或结果不正确者均不得分)。调试中若发现整个程序中存在错误之处,请加以修改。
PROG1.ASM文件内容如下:
EXTRN LOAD:FAR,SAVE:FAR
N EQU 10
STAC SEGMENT STACK
DB 128 DUP()
STAC ENDS
DATA SEGMENT
SOURCE DW N DUP()
RESULT DB N+1 DUP(0)
NAME0 DB INPUT1.DAT',0
NAME1 DB OUTPUT1.DAT',0
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STAC
START PROC FAR
PUSH DS
XOR AX,AX
PUSH AX
MOV AX,DATA
MOV DS,AX
LEA DX,SOURCE ;数据区起始地址
LEA SI,NAME0 ;原始数据文件名
MOV CX,N*2 ;字节数
CALL LOAD ;从'INPUT1.DAT'中读取数据
;* * * * BECIN * * * *
MOV DI,OFFSET RESULT
MOV CL,N
MOV BX,0
MOV DH,0
PRO: MOV DL,0
MOV AX,SOURCE[BX]
MOV CH,______
COUNT: _____ _____
_____ JUMP
INC DL
JUMP: DEC CH
JNZ _____
MOV [DI],DL
ADD DH,DL
INC DI
ADD _____
DEC CL
JNZ PRO
&nbs
有以下程序(提示:程序中fseek(fp,-2L*sizeof(int),SEEK_END);语句的作用是使位置指针从文件末尾向前移2 * sizeof(int)字节): #include <stdio.h> main() { FILE *fp; int i, a[4]={1,2,3,4},b; fp=fopen("data.dar","wb"); for(i=0;i<4;i++) fwrite(&a[i],sizeof(int),1,fp); fclose(fp); fp=fopen("data.dar","rb"); fseek(fp,-2L*sizeof(int),SEEK_END); fread(&b,sizeof(int),1,fp); /*从文件中读取sizeof(int)字节的数据到变量b中*/ fclose(fp); printf("%d\n",b); } 执行后的输出结果()。
A.2
B.1
C.4
D.3
请编制程序,其功能是:内存中连续存放着两个无符号字节数序列Ak和Bk (k=0,1,…,9),求序列Ck,Ck=Ak÷Bk (运算结果按序以字的形式连续存放,其中低字节为商,高字节为余数)。
例如:
序列Ak为:01H,7FH, 80H,FFH…
序列Bk为:PFH,80H,7FH,01H…
结果Ck为:0100H(00H为商、01H为余数),7F00H,0101H,00FFH…
部分程序已给出,其中原始数据由过程LOAD从文件INPUT.DAT中读入SOURCE开始的内存单元中,运算结果要求从 RESULT开始存放,由过程SAVE保存到文件OUTPUT.DAT中。
请填空BEGIN和END之间已给出的源程序使其完整,空白已用横线标出,每个空白一般只需一条指令,但采用功能相当的多条指令亦可,或删除BEGm和END之间原有的代码并自行编程来完成所要求的功能。
对程序必须进行汇编,并与IO.OBJ链接产生可执行文件,最终运行程序产生结果。调试中若发现整个程序中存在错误之处,请加以修改。
[试题程序]
EXTRN LOAD:FAR,SAVE:FAR
N EQU 10
STAC SEGMENT STACK
DB 128 DUP()
STAC ENDS
DATA SEGMENT
SOURCE DB N*2 DUP()
RESULT DW N DUP(0)
NAME0 DB 'INPUT.DAT',0
NAME1 DB 'OUTPUT.DAT',0
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA, SS:STAC
START PROC FAR
PUSH DS
XOR AX,AX
PUSH AX
MOV AX,DATA
MOV DS,AX
LEA DX,SOURCE ;数据区起始地址
LEA SI,NAME0 ;原始数据文件名
MOV CX,N*2 ;字节数
CALL LOAD ;从 'INPUT.DAT' 中读取数据
; ******** BEGIN ********
MOV DI,OFFSET RESULT
MOV BX,0
(1)
PRO: MOV (2)
(3) ,SOURCE[BX]
CBW
DIV (4)
MOV [DI], (5)
ADD DI,2
(6)
DEC CX
(7) PRO
; ******** END ********
LEA DX,RESULT ;结果数据区首址
LEA SI,NAME1 ;结果文件名
MOV CX,2*N ;结果字节数
CALL SAVE ;保存结果到文件
RET
START ENDP
CODE ENDS
END START
阅读下列程序说明和C代码,将应填入(n)处的字句写在对应栏内。
【说明】
本程序从若干个原始文件合并成的合并文件中恢复出其中一个或全部原始文件。所有文件均作为二进制文件进行处理。合并文件中先顺序存储各原始文件,然后顺序存储各原始文件的控制信息,即文件名、文件长度和在合并文件中的位置(偏移量)。其结构为:
typedef struct {char fname [256] /*原始文件名*/
long length; /*原始文件长度(字节数)*/
long offset; /*原始文件在合并文件中的位置(偏移量)*/
}FileInfo;
在合并文件最后存储如下一个特殊的标志信息作为合并文件的结束标记:
FileInfo EndFlag={"Combined File",0,_offset};
其中_offset是第一个原始文件的控制信息在合并文件中的位置(偏移量)。
启动本程序的命令行的格式是:
程序名 合并文件名 [原始文件名]
如果不指定原始文件名,默认恢复合并文件中的所有原始文件。
程序中涉及的部分文件操作的库函数简要说明如下:
int fread(void * buffer,int size,int count,FILE * fbin):从二进制文件流fbin中读取 count块长度为size字节的数据块到buffer指向的存储区。返回值为实际读取的数据块数。
int fwrite(void * buffer,int size,int count,FILE * fbin):各参数和返回值的意义与fread相同,但对文件进行写操作。
int fseek(FILE * fbin,long offset,int position):将文件流fbin的读/写位置以position为基准移动offset字节。position的值可以是SEEK_SET(文件头),SEEK_CUR(当前位置), SEEK_END(文件尾);offset为正,表示向文件尾方向移动,为负表示向文件头方向移动,为零表示到基准位置。
long ftell(FILE * fbin):返回文件流fbin的当前读/写位置(相对于文件头的偏移量)。上述偏移量均以字节为单位,即偏移字节数。
【程序】
include <stdio. h>
include <string. h>
typedef struct { char fname[256];long lengt;long offset;
} Filelnfo;
void copyfile(FILE*fin, FILE * fout,int fsize)
{ char buf[1024];int siz=1024;
while(fsize !=0){ /*每次复制siz个字节,直至复制完fsize个字节*/
if(siz >fsize) (1);
fread(buf,1,siz,fin); fwrite(buf,1,siz,fout);
fsize=(2);}
}
int dofile(FILE * fin,Filelnfo * inp)
{ long offset;
FILE * fout;
if ((fout = fopen (inp - > fname ,"wb" ))==NULL) {
printf("创建文件错误: %s\n" , inp -> fname);
return 1;
}
offset=(3); /*保留合并文件读/写位置*/
fseek((4)); /*定位于被恢复文件首*/
copyfile (fin, fout, inp - > length);
fclose(fout);
printf("\n ---文件名: %\n 文件长: %ld. \n",inp -> fname, inp -> length);
(5); /*恢复合并文件读/写位置*/
return 0;
}
int main(int argc, char * argv[ ])
{ Filelnfo finfo;
char fname[256] ;FILE * fcmbn;
if(argc <2) { printf("输入合并文件名:" ) ;scanf("%s" ,fname);
else strcpy(fname,argv[1]);
if((fcmbn = fopen(fname,"rb" )) == NULL) {
printf("文件打开错误: %s\n" ,fname);return 1;
}
fseek(fcmbn, -sizeof(Filelnfo),SEEK_END); /*定位于合并文件末尾的标志信息*/
fread(&finfo,1,sizeof(Filelnfo) ,fcmbn);
if(finfo. length!=0||strcmp(finfo. fnane," CombinedFile" )){
printf("指定的文件不是合法的合并文件\n");
fclose (fcmbn); return 2;
}
fseek(fcmbn,finfo. offset,SEEK_SET); /*定位于首个原始文件的控制信息*/
for(;;){ /*恢复一个(argc>2)或全部(argc=2)原始文件*/
fread (&finfo,1, sizeof (Fitelnfo), fcmbn);
if(finfo, length ==0) break;
if (argc> 2 && strcmp(finfo. fname,argv[2] )) continue;
if (dofile (fcmbn, &finfo)!=0) break;
}
fcolse(fcmbn);return 0;
●试题四
阅读下列程序说明和C代码,将应填入(n)处的字句写在答题纸的对应栏内。
【说明】
本程序从若干个原始文件合并成的合并文件中恢复出其中一个或全部原始文件。所有文件均作为二进制文件进行处理。合并文件中先顺序存储各原始文件,然后顺序存储各原始文件的控制信息,即文件名、文件长度和在合并文件中的位置(偏移量 )。其结构为:
typedef struct{char fname [256]/*原始文件名*/
long length;/*原始文件长度(字节数)*/
long offset;/*原始文件在合并文件中的位置(偏移量)*/
}FileInfo;
在合并文件最后存储如下一个特殊的标志信息作为合并文件的结束标记:
FileInfo EndF1ag={"Combined File",0,_offset};
其中_offset是第一个原始文件的控制信息在合并文件中的位置(偏移量)。
启动本程序的命令行的格式是:
程序名合并文件名[原始文件名]
如果不指定原始文件名,默认恢复合并文件中的所有原始文件。
程序中涉及的部分文件操作的库函数简要说明如下:
int fread (void *buffer,int size,int count,FILE *fbin):从二进制文件流fbin中读取count块长度为size字节的数据块到buffer指向的存储区。返回值为实际读取的数据块数。
int fwrite(void *buffer,int size,int count,FILE *fbin):各参数和返回值的意义与fread相同,但对文件进行写操作。
int fseek(FILE *fbin,long offset,int position):将文件流fbin的读/写位置以position为基准移动offset字节。position的值可以是SEEK_SET(文件头),SEEK_CUR(当前位置),SEEK_END(文件尾);offset为正,表示向文件尾方向移动,为负表示向文件头方向移动,为零表示到基准位置。
long ftell(FILE *fbin):返回文件流fbin的当前读/写位置(相对于文件头的偏移量)。上述偏移量均以字节为单位,即偏移字节数。
【程序】
#include <stdio.h>
#include<string.h>
typedef struct{char fname[256];long length;long offset;
}FileInfo;
void copyfile(FILE *fin,FILE *fout,int fsize)
{char buf[1024];int siz=1024;
while(fsize !=0){/*每次复制siz个字节,直至复制完fsize个字节*/
if(siz >fsize) (1) ;
fread(buf,1,siz,fin);fwrite(buf,1,siz,fout);
fsize= (2) ;}
}
int dofile(FILE *fin,FileInfo *inp)
{ long offset;
FILE *fout;
if((fout=fopen(inp->fname,"wb"))==NULL){
printf("创建文件错误:%s\n",inp->fname);
return 1;
}
offset= (3) ;/*保留合并文件读/写位置*/
fseek((4) );/*定位于被恢复文件首*/
copyfile(fin,fout,inp->length);
fclose(fout);
printf("\n---文件名:%\n文件长:%1d.
\n",inp->fname,inp->length);
(5) ;/*恢复合并文件读/写位置*/
return 0;
}
int main(int argc,char *argv[])
{FileInfo finfo;
char fname[256];FILE *fcmbn;
if(argc<2){printf("输入合并文件名:");scanf("%s",fname);}
else strcpy(fname,argv[1]);
if((fcmbn=fopen(fname,"rb"))==NULL){
printf("文件打开错误:%s\n",fname);return 1;
}
fseek(fcmbn,-sizeof(FileInfo),SEEK_END);/*定位于合并文件末尾的标志信息*/
fread(&finfo,1,sizeof(FileInfo),fcmbn);
if(finfo.length!=0 || strcmp(finfo.fnane,"CombinedFile")){
printf("指定的文件不是合法的合并文件\n");
fclose(fcmbn);return 2;
}
fseek(fcmbn,finfo.offset,SEEK_SET);/*定位于首个原始文件的控制信息*/
for(;;){/*恢复一个(argc>2)或全部(argc=2)原始文件*/
fread(&finfo,1,sizeof(FileInfo),fcmbn);
if(finfo.length==0)break;
if(argc>2 && strcmp(finfo.fname,argv[2]))continue;
if(dofile(fcmbn,&finfo)!=0)break;
}
fcolse(fcmbn);return 0;
}