问答题 已知在文件in.dat中存有100个产品销售记录,每个产品销售记录由产品代码dm(字符型4位),产品名称me(字符型10位),单价dj(整型),数量sl(整型),金额je(长整型)五部分组成。其中:金额=单价*数量。函数ReadDat()读取这100个销售记录并存入结构数组sell中。请编制函数SortDat(),其功能要求:按产品代码从大到小进行排列,若产品代码相同,则按金额从大到小进行排列,最终排列结果仍存入结构数组sell中。最后main()函数调用函数writeDat()把结果输出到文件out.dat中。
提示:若中间变量为PRO temp,则可以直接使用结构赋值语句进行解题;产品代码比较请用函数strcmp进行解题。
例如:sell[i]=temp;
请勿改动主函数main()、读函数ReadDat()和输出函数WfiteDat()的内容。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 100
typedef struct
{
char dm[5]; /*产品代码*/
char mc[11]; /*产品名称*/
int dj; /*单价*/
int sl; /*数量*/
long je; /*金额*/
}PRO; //定义结构体PRO
PRO sell[MAX]; //定义结构体一维数组变量sell[MAX]
void ReadDat();
void WriteDat();
void SortDat()
{
}
void main()
{
memset(sell, 0, sizeof(sell)); //为sell分配sizeof(sell)大小的内存空间
ReadDat();
SortDat();
WriteDat();
}
/*读取这100个销售记录并存入结构数组sell中*/
void ReadDat()
{
FILE *fp;
char str[80], ch[11];
int i;
fp=fopen("in.dat", "r");
for(i=0; i<100; i++)
{
fgets(str, 80, fp); //从文件in.dat中读取长度为79的字符串存入字符数组str中
memcpy(sell[i].dm, str, 4); //从字符串str的开始位置取长度为4的字符串赋给产品代码
memcpy(sell[i].mc, str+4, 10); //从字符串str+4的位置取长度为i0的字符串赋给产品名称
memcpy(ch, str+14, 4); //从字符串str+14的位置取长度为4的字符串赋给字符数组ch
ch[4]=0; //把零赋给字符数组元素ch[4]
sell[i].dj=atoi(ch); //把字符数组ch转化成整型数值赋给产品单价
memcpy(ch, str+18, 5); //A字符串str+18的位置取长度为5的字符串赋给字符数组ch
ch[5]=0; //把零赋给字符数组元素ch[5]
sell[i].sl=atoi(ch); //把字符数组ch转化成整型数值赋给产品数量
sell[i].je=(long) sell [i].dj * sell[i].sl; //产品单价乘以产品数量等于产品金额
}
fclose (fp);
}
/*把结果输出到文件out.dat中*/
void WriteDat ()
{
FILE *fp;
int i;
fp=fopen ("out.dat", "w");
/*把经过处理的100条记录写入到文件out.dat*/
for(i=0; i<100; i++)
{
fprintf(fp, "%s %s %4d %5d %ld\n", sell[i].dm, sell[i].mc, sell[i].dj, sell[i].sl,
sell[i].je);
}
fclose(fp);
}
【正确答案】
【答案解析】int i, j, len;
PRO tmp;
len=sizeof(tmp); //调用sizeof()函数计算结构体变量tmp的长度
memset((PRO*)&tmp, 0, len); //为结构体变量tmp分配len大小的内存空间
/*对100条记录按产品代码从大到小进行排列,若产品代码相同,则按金额从大到小进行排列*/
for(i=0; i<100; i++)
for(j=i+1; j<100; j++)
{
/*若sell[i]产品代码小于sell[j]产品代码或两者产品代码相同且sell[i]金额小于sell[j]金额,则两者互换*/
if(strcmp(sell[i].dm, sell[j].dm)<0 || (sell[i].je<sell[j].je &&
strcmp(sell[i].dm, sell[j].dm)==0))
{
memcpy((PRO*) & tmp, (PRO*) & sell[i], len); //把sell[i]的值复制到tmp
memcpy((PRO*) & sell[i], (PRO*) & sell[j], len); //把sell[j]的值复制到sell[i]
memcpy((PRO*) & sell[j], (PRO*) & tmp, len); //把tmp的值复制到sell[j]
}
} [解析] 计算金额,按产品代码从大到小进行排列,相同的则按金额从大到小排列,结果存入结构数组。
①首先定义两个循环变量i、j;一个用来保存结构体变量长度的计算结果的变量len;一个用于中间转换数据的结构体变量tmp。
②计算结构体变量长度,并按结构体变量tmp分配len大小的内存空间。
③建立两个for循环,指定第一个for循环的循环变量i从0开始,到100时结束,每循环一次,变量i的值加1;第2个for循环的循环变量i从i+1开始,即从当前行的下一行开始,到100时结束,每循环一次,变量i的值加1。
④在循环体中指定排序的条件,分两个步骤指定,第一步通过strcmp()函数判断第i行的产品代码与其后面各行中产品代码的大小关系;第二步,如果比较的两行中产品代码相同的话,则再比较金额的大小。当第i行的产品代码小于后面比较行的产品代码,又或者产品代码相同时,第i行的金额小于后面比较行的金额时,将执行if条件语句后面花括号中的命令,花括号中3条命令的功能就是根据题目要求实现将记录从大到小的排序。