计算机二级C语言上机真题(9)【附详解】
【真题1】 程序通过定义学生结构体变量,存储了学生的学号、姓名和3门课的成
绩。所有学生数据均以二进制方式输出到文件中。函数fun 的功能是从形参
filename 所指的文件中读入学生数据,并按照学号从小到大排序后,再用二进制方
式把排序后的学生数据输出到filename 所指的文件中,覆盖原来的文件内容。
#include < stdio.h >
#define N 5
typedef struct student {
long sno;
char name[10];
float score[3];
} STU;
void fun(char *filename)
{ FILE *fp; int i, j;
STU s[N], t;
/**********found**********/
fp = fopen(filename, __1__);
fread(s, sizeof(STU), N, fp);
fclose(fp);
for (i=0; i< N-1; i++)
for (j=i+1; j< N; j++)
/**********found**********/
if (s[i].sno __2__)
{ t = s[i]; s[i] = s[j]; s[j] = t; }
fp = fopen(filename, "wb");
/**********found**********/
__3__(s, sizeof(STU), N, fp);
fclose(fp);
}
main()
{ STU t[N]={ {10005,"ZhangSan", 95, 80, 88},
{10003,"LiSi", 85, 70, 78},
{10002,"CaoKai", 75, 60, 88},
{10004,"FangFang", 90, 82, 87},
{10001,"MaChao", 91, 92, 77}}, ss[N];
int i,j; FILE *fp;
fp = fopen("student.dat", "wb");
fwrite(t, sizeof(STU), 5, fp);
fclose(fp);
printf("\n\nThe original data :\n\n");
for (j=0; j< N; j++)
{ printf("\nNo: %ld Name: %-8s Scores:
",t[j].sno, t[j].name);
for (i=0; i< 3; i++) printf("%6.2f ",
t[j].score[i]);
printf("\n");
}
fun("student.dat");
printf("\n\nThe data after sorting :\n\n");
fp = fopen("student.dat", "rb");
fread(ss, sizeof(STU), 5, fp);
fclose(fp);
for (j=0; j< N; j++)
{ printf("\nNo: %ld Name: %-8s Scores:
",ss[j].sno, ss[j].name);
for (i=0; i< 3; i++) printf("%6.2f ",
ss[j].score[i]);
printf("\n");
}
}
(2011年2月)
解析: 本题的考核点是结构体类型变量的定义和引用以及文件函数的应用。
fopen 函数的作用是打开一个文件,在fun 函数中为输入打开一个二进制文
件,所以第一个空填:"rb"或与此语句功能相同的语句;利用嵌套循环语句按学
号从小到大排序,所以第二个空填: >s[j].sno或与此语句功能相同的语句;
再用二进制方式把排序后的数据输出到指定文件中,fwrite函数的作用是往文
件的当前位置写入指定字节的数据块,所以第三个空填:fwrite。
答案:【1】“rb” 【2】s[j].sno 【3】fwrite
【真题2】 给定程序modi.c 中,函数fun 的功能是:用冒泡法对6 个字符串按由
小到大的顺序进行排序。 请改正程序中的错误,使它能得出正确的结果。 注意:不
要改动main 函数,
#include < stdio.h >
#include < conio.h >
#define MAXLINE 20
fun(char *pstr[6])
{ int i,j;
char *p;
for (i=0;i< 5;i++) {
for(j=i+1;j< 6;j++) {
/************found************/
if(strcmp(*(pstr+i),pstr+j) >0)
{
p=*(pstr+i);
/************found************/
*(pstr+i)=pstr+j;
*(pstr+j)=p;
}
}
}
}
main()
{int i;
char *pstr[6],str[6][MAXLINE];
clrscr();
for(i=0;i< 6;i++) pstr[i]=str[i];
printf("\nEnter 6 string(1 string at each line):\n");
for (i=0;i< 6;i++) scanf("%s",pstr[i]);
fun(pstr);
printf("The strings after sorting:\n");
for(i=0;i< 6;i++) printf("%s\n",pstr[i]);
}
(2011年2月)
解析: 首先,我们必须先读懂题中程序的大致意思,这是发现并改正程序中错
误的重要前提。
程序中的重要思想如下:
1、建立了一个二维字符串数组,用于存放用户输入的6 个字符串;
2、建立了一个指针数组,目的是用6 个指针分别指向6 个字符串;
3、函数fun()的形参只有一个,即指针数组pstr[],这表明要想在函数fun()
中对6 个字符串进行操作,只能通过pstr[]中的6个指针。
题中第一个错误是在应用函数strcmp()的时候:观察源程序可以发现,在程序
中使用strcmp()函数的原意是为了判断字符串str[i]与str[i+1]两者的大小,
在fun()函数中只能通过指针来引用各个字符串,故应当使用*(pstr+x)的形式
来表示,而在使用strcmp()字符串比较函数的时候,第二个参数没有正确的表
示一个字符串,所以应当将"pstr+j"改为"*(pstr+j)";
题中第二个错误是在函数fun()中的语句" *(pstr + i) = pstr + j ;"处,此语
句的原意是进行字符串的赋值操作,错误和第一个错误大致是一样的,所以应
当将"pstr+j"改为"*(pstr+j)"。
在函数中通过指针引用字符串的方式是灵活的,譬如本题中也可以使用
pstr[i]、pstr[j]类似的方法进行表示。
【真题3】 请编写函数fun(),该函数的功能是按条件删除一个字符串指定字符一半
的数目,具体要求如下:如果该字符串所包含的指定字符的个数是奇数,则不予删
除,如果其数目是偶数,则删除原串后半部分的指定字符。其中,a 指向原字符串,
删除后的字符串存放在b 所指的数组中,c 中存放指定的字符。例如:当a 输入
“abababa”,c=‘a’时,b 的输出为“ababb”;如果a 的输入为“ababa”,则b的输出
为“ababa”。 注意:部分源程序给出如下。 试题程序:
#include< stdio.h >
#include< conio.h >
#define LEN 80
void fun(char a[],char b[],char c)
{……}
main()
{ char a[LEN],b[LEN];
char c;
clrscr();
printf("Enter the string:\n");
gets(a);
printf("Enter the character of the
string deleted:");
scanf("%c",&c);
fun(a,b,c);
printf("The new string is : %s\n",b);
}
(2011年2月)
解析: fun 函数编写如下:
int i=0,j=0;
int n=0;
int m=0;
while(a[i]!='\0')
{ if(a[i]==c)
n++;
i++;
}
i=0;
if(n%2)
{
while(a[j]!='\0')
{
b[j]=a[j];
j++;
}
b[j]='\0';
}
else
{
while(a[i]!='\0')
{
b[j++]=a[i];
if(a[i]==c)
m++;
if((m >n/2)&&(a[i]==c))
j--;
i++;
}
b[j]= ′ \0 ′;
}
绩。所有学生数据均以二进制方式输出到文件中。函数fun 的功能是从形参
filename 所指的文件中读入学生数据,并按照学号从小到大排序后,再用二进制方
式把排序后的学生数据输出到filename 所指的文件中,覆盖原来的文件内容。
#include < stdio.h >
#define N 5
typedef struct student {
long sno;
char name[10];
float score[3];
} STU;
void fun(char *filename)
{ FILE *fp; int i, j;
STU s[N], t;
/**********found**********/
fp = fopen(filename, __1__);
fread(s, sizeof(STU), N, fp);
fclose(fp);
for (i=0; i< N-1; i++)
for (j=i+1; j< N; j++)
/**********found**********/
if (s[i].sno __2__)
{ t = s[i]; s[i] = s[j]; s[j] = t; }
fp = fopen(filename, "wb");
/**********found**********/
__3__(s, sizeof(STU), N, fp);
fclose(fp);
}
main()
{ STU t[N]={ {10005,"ZhangSan", 95, 80, 88},
{10003,"LiSi", 85, 70, 78},
{10002,"CaoKai", 75, 60, 88},
{10004,"FangFang", 90, 82, 87},
{10001,"MaChao", 91, 92, 77}}, ss[N];
int i,j; FILE *fp;
fp = fopen("student.dat", "wb");
fwrite(t, sizeof(STU), 5, fp);
fclose(fp);
printf("\n\nThe original data :\n\n");
for (j=0; j< N; j++)
{ printf("\nNo: %ld Name: %-8s Scores:
",t[j].sno, t[j].name);
for (i=0; i< 3; i++) printf("%6.2f ",
t[j].score[i]);
printf("\n");
}
fun("student.dat");
printf("\n\nThe data after sorting :\n\n");
fp = fopen("student.dat", "rb");
fread(ss, sizeof(STU), 5, fp);
fclose(fp);
for (j=0; j< N; j++)
{ printf("\nNo: %ld Name: %-8s Scores:
",ss[j].sno, ss[j].name);
for (i=0; i< 3; i++) printf("%6.2f ",
ss[j].score[i]);
printf("\n");
}
}
(2011年2月)
解析: 本题的考核点是结构体类型变量的定义和引用以及文件函数的应用。
fopen 函数的作用是打开一个文件,在fun 函数中为输入打开一个二进制文
件,所以第一个空填:"rb"或与此语句功能相同的语句;利用嵌套循环语句按学
号从小到大排序,所以第二个空填: >s[j].sno或与此语句功能相同的语句;
再用二进制方式把排序后的数据输出到指定文件中,fwrite函数的作用是往文
件的当前位置写入指定字节的数据块,所以第三个空填:fwrite。
答案:【1】“rb” 【2】s[j].sno 【3】fwrite
【真题2】 给定程序modi.c 中,函数fun 的功能是:用冒泡法对6 个字符串按由
小到大的顺序进行排序。 请改正程序中的错误,使它能得出正确的结果。 注意:不
要改动main 函数,
#include < stdio.h >
#include < conio.h >
#define MAXLINE 20
fun(char *pstr[6])
{ int i,j;
char *p;
for (i=0;i< 5;i++) {
for(j=i+1;j< 6;j++) {
/************found************/
if(strcmp(*(pstr+i),pstr+j) >0)
{
p=*(pstr+i);
/************found************/
*(pstr+i)=pstr+j;
*(pstr+j)=p;
}
}
}
}
main()
{int i;
char *pstr[6],str[6][MAXLINE];
clrscr();
for(i=0;i< 6;i++) pstr[i]=str[i];
printf("\nEnter 6 string(1 string at each line):\n");
for (i=0;i< 6;i++) scanf("%s",pstr[i]);
fun(pstr);
printf("The strings after sorting:\n");
for(i=0;i< 6;i++) printf("%s\n",pstr[i]);
}
(2011年2月)
解析: 首先,我们必须先读懂题中程序的大致意思,这是发现并改正程序中错
误的重要前提。
程序中的重要思想如下:
1、建立了一个二维字符串数组,用于存放用户输入的6 个字符串;
2、建立了一个指针数组,目的是用6 个指针分别指向6 个字符串;
3、函数fun()的形参只有一个,即指针数组pstr[],这表明要想在函数fun()
中对6 个字符串进行操作,只能通过pstr[]中的6个指针。
题中第一个错误是在应用函数strcmp()的时候:观察源程序可以发现,在程序
中使用strcmp()函数的原意是为了判断字符串str[i]与str[i+1]两者的大小,
在fun()函数中只能通过指针来引用各个字符串,故应当使用*(pstr+x)的形式
来表示,而在使用strcmp()字符串比较函数的时候,第二个参数没有正确的表
示一个字符串,所以应当将"pstr+j"改为"*(pstr+j)";
题中第二个错误是在函数fun()中的语句" *(pstr + i) = pstr + j ;"处,此语
句的原意是进行字符串的赋值操作,错误和第一个错误大致是一样的,所以应
当将"pstr+j"改为"*(pstr+j)"。
在函数中通过指针引用字符串的方式是灵活的,譬如本题中也可以使用
pstr[i]、pstr[j]类似的方法进行表示。
【真题3】 请编写函数fun(),该函数的功能是按条件删除一个字符串指定字符一半
的数目,具体要求如下:如果该字符串所包含的指定字符的个数是奇数,则不予删
除,如果其数目是偶数,则删除原串后半部分的指定字符。其中,a 指向原字符串,
删除后的字符串存放在b 所指的数组中,c 中存放指定的字符。例如:当a 输入
“abababa”,c=‘a’时,b 的输出为“ababb”;如果a 的输入为“ababa”,则b的输出
为“ababa”。 注意:部分源程序给出如下。 试题程序:
#include< stdio.h >
#include< conio.h >
#define LEN 80
void fun(char a[],char b[],char c)
{……}
main()
{ char a[LEN],b[LEN];
char c;
clrscr();
printf("Enter the string:\n");
gets(a);
printf("Enter the character of the
string deleted:");
scanf("%c",&c);
fun(a,b,c);
printf("The new string is : %s\n",b);
}
(2011年2月)
解析: fun 函数编写如下:
int i=0,j=0;
int n=0;
int m=0;
while(a[i]!='\0')
{ if(a[i]==c)
n++;
i++;
}
i=0;
if(n%2)
{
while(a[j]!='\0')
{
b[j]=a[j];
j++;
}
b[j]='\0';
}
else
{
while(a[i]!='\0')
{
b[j++]=a[i];
if(a[i]==c)
m++;
if((m >n/2)&&(a[i]==c))
j--;
i++;
}
b[j]= ′ \0 ′;
}