任务1:
要求:
在当前用户目录下创建数据 文件student.txt,文件的内部信息存储格式为Sname:S#:Sdept:Sage:Ssex,即“姓名:学号:学院:年龄:性别”,每行一条记录,输入不少于10条学生记录,其中包括学生本人记录。编写程序task41.c,从文件中查找Sdept字段值为“计算机与网络安全学院”的文本行,输出到文件csStudent.txt中,保存时各字段顺序调整为S#:Sname:Sage: Ssex:Sdept。
设计思想:
先用文件指针fp1与fp2分别打开文件student.txt与csStudent.txt,再对student,txt文件进行读取,每次读取1行成为字符串,当读取到的字符串里有“计算机与网络安全学院”时,将这个字符串写入csStudent.txt文件里。最后关闭两个文件。
#include<stdio.h>
#include <string.h>
#define MAXSIZE 100
int main(){
FILE *fp1,*fp2;
char buf[MAXSIZE];
char fit[]="计算机与网络安全学院";
if ((fp1 = fopen("student.txt", "r")) == NULL)
{
printf("Open Failed!");
}
if ((fp2 = fopen("csStudent.txt", "a+")) == NULL)
{
printf("Open Failed!");
}
while(!feof(fp1))
{
fgets(buf, MAXSIZE, fp1);
if (strstr(buf, fit))
{
fputs(buf, fp2);
}
}
fclose(fp1);
fclose(fp2);
}
任务2:
要求:
调用Unix I/O库函数,编写程序task42.c,从键盘读入5个学生的成绩信息,包括学号、姓名、语文、数学、英语,成绩允许有一位小数,存入一个结构体数组,结构体定义为:
typedef struct _subject {
char sno[20]; //学号
char name[20]; //姓名
float chinese; //语文成绩
float math; //数学成绩
float english; //英语成绩
} subject;
将学生信息,逐条记录写入数据文件data,最后读回第1、3、5条学生成绩记录,显示出来,检查读出结果是否正确。
设计思想:
将从键盘读取数据后写入data文件这个步骤重复5遍,然后从data文件读取数据到结构体数组su1中,最后显示第1,第3,第5条学生成绩记录。
#include<stdio.h>
#include<fcntl.h>
#include<sys/types.h>
#include<unistd.h>
typedef struct _subject {
char sno[20]; //学号
char name[20]; //姓名
float chinese; //语文成绩
float math; //数学成绩
float english; //英语成绩
} subject;
int main(){
subject su1[5];
subject as;
int fd=open("data",O_WRONLY|O_CREAT|O_TRUNC,0777);
for(int i = 0;i < 5; i ++){
printf("该学生的学号为:\n");
scanf("%s", &as.sno);
printf("该学生的姓名为:\n");
scanf("%s", &as.name);
printf("该学生的语文成绩为:\n");
scanf("%f", &as.chinese);
printf("该学生的数学成绩为:\n");
scanf("%f", &as.math);
printf("该学生的英语成绩为:\n");
scanf("%f", &as.english);
write(fd,(void*)&as,sizeof(subject));
}
close(fd);
fd=open("data",O_RDONLY,0);
for(int i = 0;i < 5;i ++)
read(fd,(void*)&su1[i],sizeof(subject));
for(int i = 0;i < 5; i+=2){
printf("%s %s %.1f %.1f
%.1f\n",su1[i].sno,su1[i].name,su1[i].chinese,su1[i].math,su1[i].english);
}
close(fd);
}
任务3:
要求:
在Linux环境下,可以调用库函数gettimeofday测量一个代码段的执行时间,请写一个程序task43.c,测量read、write、fread、fwrite函数调用所需的执行时间,并与prof/gprof工具测的结果进行对比,看是否基本一致。并对四个函数的运行时间进行对比分析。
提示:由于一次函数调用时间太短,测量误差太多,应测量上述函数多次(如10000次)运行的时间,结果才会准确。
设计思想:
用fd指针创建文件后使用write函数写入10000个a进去,写入前与写入后都用gettimeofday函数记录当时的时间,后关闭fd。接下来用fd指针打开文件后使用read函数读取1字节10000次,读取前和读取后都用gettimeofday函数记录当时的时间,后关闭fd。
用fp文件指针创建文件后使用fwrite函数写入10000个a进去,写入前与写入后都用gettimeofday函数记录当时的时间,后关闭fp。接下来用fp指针打开文件后fread函数读取1字节10000次,读取前和读取后都用gettimeofday函数记录当时的时间,后关闭fp。
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
void wewrite(int fd)
{
for (int i = 0; i < 10000000; i++)
write(fd, "a", 1);
}
void weread(int fd, char a[4])
{
for (int i = 0; i < 100000000; i++)
read(fd, a, 1);
}
void wefread(FILE *fp, char a[4])
{
for (int i = 0; i < 100000000; i++)
fread(a, sizeof(char), 1, fp);
}
void wefwrite(FILE *fp)
{
for (int i = 0; i < 100000000; i++)
fwrite("a", sizeof(char), 1, fp);
}
int main()
{
struct timeval tp;
struct timeval tp1;
double g_time_start;
double g_time_end;
//测量write函数
int fd = open("test.txt", O_WRONLY | O_CREAT | O_TRUNC, 0777);
gettimeofday(&tp, NULL);
g_time_start = tp.tv_sec * 1000000 + tp.tv_usec;
for (int i = 0; i < 10000; i++)
write(fd, "a", 1);
gettimeofday(&tp1, NULL);
g_time_end = tp1.tv_sec * 1000000 + tp1.tv_usec;
printf("write函数的运行时间为:%.4f微秒\n", (g_time_end - g_time_start) / 10000);
close(fd);
//测量read函数
fd = open("test.txt", O_RDONLY, 0);
char a[4];
gettimeofday(&tp, NULL);
g_time_start = tp.tv_sec * 1000000 + tp.tv_usec;
for (int i = 0; i < 10000; i++)
read(fd, a, 1);
gettimeofday(&tp1, NULL);
g_time_end = tp1.tv_sec * 1000000 + tp1.tv_usec;
printf("read函数的运行时间为:%.4f微秒\n", (g_time_end - g_time_start) / 10000);
//使用gprof工具测量write函数
close(fd);
fd = open("test.txt", O_WRONLY | O_CREAT | O_TRUNC, 0777);
wewrite(fd);
close(fd);
//使用gprof工具测量read函数
fd = open("test.txt", O_RDONLY, 0);
weread(fd, a);
close(fd);
//测量fwrite函数
FILE *fp = fopen("test.txt", "w");
gettimeofday(&tp, NULL);
g_time_start = tp.tv_sec * 1000000 + tp.tv_usec;
for (int i = 0; i < 10000; i++)
fwrite("a", sizeof(char), 1, fp);
gettimeofday(&tp1, NULL);
g_time_end = tp1.tv_sec * 1000000 + tp1.tv_usec;
printf("fwrite函数的运行时间为:%.4f微秒\n", (g_time_end - g_time_start) / 10000);
fclose(fp);
//测量fread函数
fp = fopen("test.txt", "r");
gettimeofday(&tp, NULL);
g_time_start = tp.tv_sec * 1000000 + tp.tv_usec;
for (int i = 0; i < 10000; i++)
fread(a, sizeof(char), 1, fp);
gettimeofday(&tp1, NULL);
g_time_end = tp1.tv_sec * 1000000 + tp1.tv_usec;
printf("fread函数的运行时间为:%.4f微秒\n", (g_time_end - g_time_start) / 10000);
fclose(fp);
//使用gprof工具测量fwrite函数
fp = fopen("test.txt", "w");
wefwrite(fp);
fclose(fp);
//使用gprof工具测量fwrite函数
fp = fopen("test.txt", "r");
wefread(fp, a);
fclose(fp);
}
任务4:
要求:
在Linux系统环境下,编写程序task44.c,对一篇英文文章文件的英文单词词频进行统计。
- 以“单词:次数”格式输出所有单词的词频(必做)
- 以“单词:次数”格式、按词典序输出各单词的词频(选做)
- 以“单词:次数”格式输出出现频度最高的10个单词的词频
设计思想:
用打开文件English.txt后读取数据,每次读取1个字符复制到cap二维数组中,当读取到终止符后结束读取;若读取到的字符为除大小写字母和终止符时,将单词与之前读取到的单词进行对比,若有相同的单词就将该单词的个数加1,若无则复制进cap数组中。之后对cap数组进行按词典从大到小排序后显示。然后对cap数组进行按出现次数进行排序后显示前10个,若单词数不足10个则显示全部单词。
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
int fd, i, j, y;
char cap[500][20], temp[20];
int num[500], count = 0, flag, isEmpty;
char c;
fd = open("English.txt", O_RDONLY, 0);
for (i = 0; i < 500; i++)
{
isEmpty = 0;
for (j = 0; j < 20; j++)
{
read(fd, &c, sizeof(char));
if ((c >= 65 && c <= 90) || (c >= 97 && c <= 122))
{
temp[j] = c;
}
else if (c == '\0')
{
isEmpty = 2;
break;
}
else
{
temp[j] = '\0';
isEmpty = 1;
break;
}
}
if (isEmpty == 2)
{
break;
}
if (isEmpty == 1)
{
flag = 0;
for (y = 0; y < count; y++)
{
if (!strcmp(cap[y], temp))
{
num[y]++;
flag = 1;
break;
}
}
if (flag == 0)
{
strcpy(cap[count], temp);
num[count] = 1;
count++;
}
}
}
for (i = 0; i < count; i++)
{
for (j = i + 1; j < count; j++)
{
if (strcmp(cap[i], cap[j]) > 0)
{
strcpy(temp, cap[i]);
strcpy(cap[i], cap[j]);
strcpy(cap[j], temp);
y = num[i];
num[i] = num[j];
num[j] = y;
}
}
}
printf("按词典序输出各单词的词频:\n");
for (i = 1; i < count; i++)
printf("%s:%d\n", cap[i], num[i]);
for (i = 0; i < count; i++)
{
for (j = i + 1; j < count; j++)
{
if (num[i] < num[j])
{
strcpy(temp, cap[i]);
strcpy(cap[i], cap[j]);
strcpy(cap[j], temp);
y = num[i];
num[i] = num[j];
num[j] = y;
}
}
}
printf("输出出现频度最高的10个单词的词频:\n");
for (i = 1; i < 11 && i < count; i++)
printf("%s:%d\n", cap[i], num[i]);
}