010-6095-7397
登录 | 注册
010-6095-7397

当前位置:中公软考> 模拟试题 >

(软考初级)程序员案例分析每日一练(2)

发布者:中公软考     来源:中公软考     2021-03-30 14:03:18     阅读()

试题三

阅读下列程序说明和C代码,将应填入__(n)__处的字句写在答题纸的对应栏内。

[程序3说明]

本程序从若干个原始文件合并成的合并文件中恢复出其中一个或全部原始文件。所有文件均作为二进制文件进行处理。合并文件中先顺序存储各原始文件,然后顺序存储各原始文件的控制信息,即文件名、文件长度和在合并文件中的位置(偏移量)。其结构为:

typedef stmct{char fnme[256];/*原始文件名*/

long length;/*原始文件长度(字节数)*/

long offset;/*原始文件在合并文件中的位置(偏移量)*/

}FileInfo;

在合并文件最后存储如下一个特殊的标志信息作为合并文件的结束标记:

F11ek1fo 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 的当前读/写位置(相对于文件头的偏移量)。上述偏移量均以字节为单位,即偏移字节数。

[程序3]

#include〈stdio.h〉

#include〈string.h〉

typedef struct{char fname[256];long length;long offset;}

}FileInfo;

void copyfile( FILE *fin, FILE *fout, int fsiz)

{ char buf[1024]; int siz = 1024 ;

while(fsiz != 0) { /*每次复制siz个字节,直至复制完fsiz个字节*/

if ( siz > fsiz) __(1)__ ;

fread( buf , 1 , siz , fin ) ; fwrite( buf , 1 , siz , fout );

fsiz = __(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 ) ; }

若在2号与3号珠子间为断点,共可取走6粒珠子,且为取走的珠子数最多。

[程序4]

#include〈stdio.h〉

#include〈string.h〉

#include〈malloc.h〉

typedef struct node { char d ;

struct node *fpt ; /*后继指针*/

struct node*bpt ; /*前趋指针*/

}NODE ;

NODE *building( char *s ) /*生成双向循环链表*/

{ NODE *p = NULL , *q ;

while ( *s ){

q = ( NODE * ) malloc( sizeof( NODE ) ) ;

q -> ch = *s++ ;

if ( p = NULL ) p = q -> fpt = q -> b t = q ;

else {

p -> bpt -> fpt = q ;

q -> fpt = p ;

q -〉bpt = __(1)__;

__(2)__ ;

}

}

return

}

int count( NODE *start , int maxn ,int step ) /*求可取走珠子粒数*/

{ int color ,c ;

NODE *p ;

color = -1 ; C = 0 ;

for ( p = start ; c O ? p -> fpt ; p -> bpt ){

if ( color == -1 ) color = p -> ch ;

else if (__(3)__) break ;

c++

}

return

}

int find ( char *s ,int *cutpos ) /*寻找取走珠子数最多的断点和粒数*/

{ int i , c , cut , maxc = 0 ,1en = strlen(s) ;

NODE *p ;

if ( ( p = building(s) ) = NULL ){ *cu1tpos = -1 ; return -1 ; }

i = 0 ;

do { c = count( p , 1en ,1 ) ;

c = c + __(4)__ ;

if ( c > maxc ) { maxc = c ; cut = i ; }

__(5)__ ;

i++ ;

} while (i < len ) ;

* cutpos = cut ;

return maxc ;

}

void main()

{ int cut , max ;

char s[120] ;

scanf( , %s', s ) ;

max = find( s , &cut ) ;

printf ( "Cut position = %d , Number = %d.\n" , cut , max ) ;

}

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.fmane , "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 ;

}

fclose( fcmbn ) ; return 0 ;

}

试题四

阅读下列程序说明和C代码,将应填入__(n)__处的字句写在答题纸的对应栏内。

[程序4说明]

设一个环上有编号为 0~n-1 的 n 粒不同颜色的珠子(每粒珠子颜色用字母表示, n 粒珠子颜色由输入的字符串表示)。以环上某两粒珠子间为断点,从断点一方按顺时针方向取走连续同色的珠子,又从断点另一方按逆时针方向对剩下珠子取走连续同色的珠子,两者之和为该断点可取走珠子的粒数。移动断点,能取走的珠子数不尽相同。本程序找出可以取走最多的珠子数及断点的位置。程序中用双向链表存储字符串。例如,编号为0-9的10粒珠子颜色的字符串为“aaabbbadcc",对应链表为:

若在2号与3号珠子间为断点,共可取走6粒珠子,且为取走的珠子数最多。

[程序4]

#include〈stdio.h〉

#include〈string.h〉

#include〈malloc.h〉

typedef struct node { char d ;

struct node *fpt ; /*后继指针*/

struct node*bpt ; /*前趋指针*/

}NODE ;

NODE *building( char *s ) /*生成双向循环链表*/

{ NODE *p = NULL , *q ;

while ( *s ){

q = ( NODE * ) malloc( sizeof( NODE ) ) ;

q -> ch = *s++ ;

if ( p = NULL ) p = q -> fpt = q -> b t = q ;

else {

p -> bpt -> fpt = q ;

q -> fpt = p ;

q -〉bpt = __(1)__;

__(2)__ ;

}

}

return

}

int count( NODE *start , int maxn ,int step ) /*求可取走珠子粒数*/

{ int color ,c ;

NODE *p ;

color = -1 ; C = 0 ;

for ( p = start ; c O ? p -> fpt ; p -> bpt ){

if ( color == -1 ) color = p -> ch ;

else if (__(3)__) break ;

c++

}

return

}

int find ( char *s ,int *cutpos ) /*寻找取走珠子数最多的断点和粒数*/

{ int i , c , cut , maxc = 0 ,1en = strlen(s) ;

NODE *p ;

if ( ( p = building(s) ) = NULL ){ *cu1tpos = -1 ; return -1 ; }

i = 0 ;

do { c = count( p , 1en ,1 ) ;

c = c + __(4)__ ;

if ( c > maxc ) { maxc = c ; cut = i ; }

__(5)__ ;

i++ ;

} while (i < len ) ;

* cutpos = cut ;

return maxc ;

}

void main()

{ int cut , max ;

char s[120] ;

scanf( , %s', s ) ;

max = find( s , &cut ) ;

printf ( "Cut position = %d , Number = %d.\n" , cut , max ) ;

}

参考答案

软考微信公众号

分享最前沿行业动态、业内时评,打造专业软考交流圈

软考QQ群

备考交流、干货共享,学习各种软考考试技巧

相关阅读

近期考试资讯

为你推荐


在线咨询

新浪微博

软考微信


返回顶部