C语言 实验七 任务报告
📝实验七 任务报告
✨实验总结
😟遇到的问题:
任务4 中如果要手动把二进制转为文本,如果要转为中文的话怎么做呢?
🧐解决方法:
在百度之后发现实力不足,目前还做不到,只好作为一个todo,还需深入学习。
🤔反思:
c语言的课程已经结束了,但是我认为这仅仅只是相当基础的部分。学习的目的不应仅仅是为了分数,而是掌握一门技能。c语言的话,我觉得以目前课本的知识来说学了还不到1%。路漫漫其修远兮,吾将上下而求索。
✨实验内容
🕐任务一
📃代码:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fs,*fp;
int ch;
fs=fopen("file1.txt","r");
if (fs==NULL)
{
printf("Fail to open file1.txt\n");
exit(0);//非正常退出
}
fp=fopen("file2.txt","w");
if (fp==NULL)
{
printf("fail to open or create file2.txt\n");
exit(0);
}
while (!feof(fs))//内容不为EOF ,不是eof的话feof的返回值不为0;
{
ch=fgetc(fs);
if (ch>='a'&&ch<='z')
ch-=32;
fputc(ch,fp);
}
fclose(fs);
fclose(fp);
return 0;
}
🎨截图:
无
🤓反思:
正常运行,正常生成。
🕑任务二
代码:
#include <stdio.h>
#include <stdlib.h>
#define N 10
typedef struct student
{
int num;
char name[20];
int score;
}STU;
int main()
{
STU st,stmax,stmin;
FILE *fp;
fp=fopen("file1.dat","r");
if (!fp)
{
printf("fail to open file1.dat\n");
exit(0);
}
stmax.score=0;
stmin.score=100;
for (int i = 0; i < N; ++i)
{
fscanf(fp,"%d %s %d",&st.num,st.name,&st.score);
if (st.score>stmax.score)
stmax=st;
if (st.score<stmin.score)
stmin=st;
}
fclose(fp);
printf("最高分学生信息:%5d%15s%5d\n",stmax.num,stmax.name,stmax.score);
printf("最低分学生信息:%5d%15s%5d\n",stmin.num,stmin.name,stmin.score);
return 0;
}
截图:
无
反思:
正常运行,正产生成。
🕒任务三
📃代码:
#include <stdio.h>
#include <stdlib.h>
#define N 10
typedef struct student
{
int num;
char name[20];
int score;
}STU;
void sort (STU *pst,int n);
int main()
{
FILE *fin,*fout;
STU st[N];
fin=fopen("file1.dat","r");
if (!fin)
{
printf("fail to open file1.dat\n");
exit(0);
}
for(int i = 0; i < N; ++i)
fscanf(fin,"%d %s %d",&st[i].num,st[i].name,&st[i].score);
fclose(fin);
sort(st,N);
fout =fopen("file3.dat","w");
if (!fout)
{
printf("fail to open file3.dat");
exit(0);
}
for (int i = 0; i < N; ++i)
{
printf("%-6d%-10s%3d\n",st[i].num,st[i].name,st[i].score);
fprintf(fout,"%-6d%-10s%3d\n",st[i].num,st[i].name,st[i].score);
}
fclose(fout);
return 0;
}
void sort (STU *pst,int n)
{
STU *pi,*pj,t;
for (pi=pst; pi<pst+n-1; pi++)
for (pj=pi+1;pj<pst+n;pj++)
if (pi->score<pj->score)
{
t=*pi;
*pi=*pj;
*pj=t;
}
}
🎨截图:
🤓反思:
这个程序很顺利,记事本打开也是可读的。但是控制台就不可读了,中文是乱码,英文正常。这是编译器的问题,貌似无解,如果评论区有对文件编码了解的人告诉我就好了。
🕓任务四
📃代码:
#include <stdio.h>
#include <stdlib.h>
#define N 10
typedef struct student
{
int num;
char name[20];
int score;
}STU;
void sort (STU *pst,int n);
int main()
{
FILE *fin,*fout;
STU st[N];
fin=fopen("file1.dat","r");
if (!fin)
{
printf("fail to open file1.dat\n");
exit(0);
}
for(int i = 0; i < N; ++i)
fscanf(fin,"%d %s %d",&st[i].num,st[i].name,&st[i].score);
fclose(fin);
sort(st,N);
fout =fopen("file4.dat","wb");
if (!fout)
{
printf("fail to open file4.dat");
exit(0);
}
for (int i = 0; i < N; ++i)
printf("%-6d%-10s%3d\n",st[i].num,st[i].name,st[i].score);
fwrite(st,sizeof(STU),N,fout);
fclose(fout);
FILE *fb;
fb=fopen("file4.dat","rb");
while( ! feof(fb) )
{
int ch;
if( (ch = fgetc(fb)) != EOF )
putchar(ch);
}
fclose(fb);
return 0;
}
void sort (STU *pst,int n)
{
STU *pi,*pj,t;
for (pi=pst; pi<pst+n-1; pi++)
for (pj=pi+1;pj<pst+n;pj++)
if (pi->score<pj->score)
{
t=*pi;
*pi=*pj;
*pj=t;
}
}
🎨截图:
🤓反思:
正常运行生成文件。
这个任务刚刚看到的时候一脸懵,以为要把二进制转为文本,后来仔细想想,应该没有这么困难,就是直接原样输出吧。。
🕔任务五
📃代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 10
typedef struct student
{
long id;
char name[20];
float obj;
float sub;
float sum;
char level[10];
}STU;
void input (STU s[],int n);
void output (STU s[],int n);
void process (STU s[],int n);
int main()
{
STU stu[N];
printf("录入%d个考生信息: 准考证号,姓名,客观题得分(<=40),操作题得分(<=60)\n", N);
input(stu, N);
printf("\n对考生信息进行处理: 计算总分,确定等级\n");
process(stu, N);
printf("\n打印考生完整信息: \n准考证号,姓名,客观题得分,操作题得分,总分,等级\n");
output(stu, N);
return 0;
}
void input (STU s[],int n)
{
FILE *fe;
fe=fopen("examinee.txt","r");
if( !fe )
{
printf("fail to open examinee.txt\n");
exit(0);
}
for (int i = 0; i < n; ++i)
fscanf(fe,"%ld %s %f %f",&s[i].id,s[i].name,&s[i].obj,&s[i].sub);
for (int i = 0; i < n; ++i)
printf("%-10ld%-10s%-10.2f%-10.2f\n",s[i].id,s[i].name,s[i].obj,s[i].sub);
}
void output (STU s[],int n)
{
FILE *ff;
ff=fopen("faults.txt","w");
if( !ff)
{
printf("fail to open faults.txt\n");
exit(0);
}
for (int i = 0; i < n; ++i)
{
printf("%-10ld%-10s%-10.2f%-10.2f%-10.2f%-10s\n",s[i].id,s[i].name,s[i].obj,s[i].sub,s[i].sum,s[i].level);
fprintf(ff,"%-10ld%-10s%-10.2f%-10.2f%-10.2f%-10s\n",s[i].id,s[i].name,s[i].obj,s[i].sub,s[i].sum,s[i].level);
}
}
void process (STU s[],int n)
{
{
int i, j, k;
STU temp;
for (i = 0; i < n; ++i)
{
s[i].sum = 0.4 * s[i].sub + 0.6 * s[i].obj;
}
for (i = 0; i < n - 1; i++)
{
k = i;
for (j = i + 1; j < n; j++)
if (s[j].sum < s[k].sum)
k = j;
if (k != i)
{
temp = s[i];
s[i] = s[k];
s[k] = temp;
}
}
for ( i = 0; i < n; ++i)
{
if (i<n/10)
strcpy(s[i].level,"优秀");
else if (i<n/2)
strcpy(s[i].level,"合格");
else
strcpy(s[i].level,"不及格");
}
}
}
🎨截图:
🤓反思:
这个任务卡了很久,原来是因为自己写的时候结构体定义name
时没有加[20]
的字符限制,导致把字符串赋值给stu[i],name
的时候出错。好在编译器的提示让我快速定位了错因。
🕕任务六
📃代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define N 5
typedef struct student
{
int num;
long id;
char name[20];
char region[20];
}STU;
int main()
{
srand((unsigned) time(NULL));
FILE *fin=NULL,*fout=NULL;
int n=1,c=0;
fin=fopen("list.txt","r");
if (!fin)
{
printf("Can't open list.txt,please try again.\n");
exit(0);
}
//求得文件行数,即数据个数
while ((c=fgetc(fin))!=EOF)
{
if (c == '\n')
n++;
}
rewind(fin);//求行数的时候文件指针到了末尾,所以想要再次读取需要将文件指针移动到文件开头
STU s[n];
int sub[N];
//把文件中的数据写入s[n]
for (int i = 0; i < n; ++i)
fscanf(fin,"%d%ld%s%s\n",&s[i].num,&s[i].id,s[i].name,s[i].region);
fclose(fin);
//求出随机不重复下标
for (int i = 0; i < N; ++i)
{
sub[i]=rand()%n;
//把sub[i]和之前的每一个数比较,相同则重新执行本次循环
for (int j = 0; j < i; ++j)
if (sub[i]==sub[j])
{
i--;
break;
}
}
time_t rawtime;
struct tm *info;
char buffer[80];
time( &rawtime );
info = localtime( &rawtime );
strftime(buffer, 80, "%Y-%m-%d %H:%M:%S", info);
printf("格式化的日期 & 时间 : |%s|\n", buffer );
//以现在系统时间作为文件名
FILE *fp = NULL;
time_t timep;
char name[256] = {0};
time(&timep);//获取从1970至今过了多少秒,存入time_t类型的timep
strftime( name, sizeof(name), "%Y.%m.%d %H-%M-%S点名数据.txt",localtime(&timep) ); //最后一个参数是用localtime将秒数转化为struct tm结构体
printf("创建文件名称为:%s\n", name);
//写入数据
fout=fopen(name,"w");
if (!fout)
{
printf("Can't open lucky.txt,please try again.\n");
exit(0);
}
for (int i = 0; i < N; ++i)
{
printf("%-10d%-10ld%-10s%-10s\n",s[sub[i]].num,s[sub[i]].id,s[sub[i]].name,s[sub[i]].region);
fprintf(fout,"%-10d%-10ld%-10s%-10s\n",s[sub[i]].num,s[sub[i]].id,s[sub[i]].name,s[sub[i]].region);
}
fclose(fout);
return 0;
}
🎨截图:
🤓反思:
实现效果:随机抽点,不重复,以系统时间命名。
思路:数据是每一行一个人的数据,那么就把每一行存入结构体数组中,随机只需要随机下标就好了。随机下标的话我又用了一个数组来存放随机数。不重复的方法是在每次生成之后检验是否与之前的每一个数重复,若重复则再次开始本次循环。
不过吃亏还是吃了,读取行数的时候文件指针已经到了文件末尾,我又疏忽了rewind
函数,于是在最开始测试的时候输出的全部都是乱码。思考了很久才想明白。