Linux实验一实验报告

实验内容与要求:

先创建用户家目录下创建文件名为“姓名+学号+04”的子目录,作为本次实验目录,本次实验的所有代码都放到该目录下,要求将所有源代码与数据文件打包成文件”学号-姓名-lab4.tar.gz”, 压缩包与实验报告分别上传到指定目录下。

任务1. 在当前用户目录下创建数据文件student.txt,文件的内部信息存储格式为Sname:S#:Sdept:Sage:Ssex,即“姓名:学号:学院:年龄:性别”,每行一条记录,输入不少于10条学生记录,其中包括学生本人记录。编写程序task41.c,从文件中查找Sdept字段值为“计算机与网络安全学院”的文本行,输出到文件csStudent.txt中,保存时各字段顺序调整为S#:Sname:Sage: Ssex:Sdept。

提示:从终端读入一个文本行到字符串 char buf[MAXSIZE]可调用函数可调用函数:

“fgets(buf, MAXSIZE, stdin);”,其中stdin是表示键盘输入设备的文件指针。

    任务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条学生成绩记录,显示出来,检查读出结果是否正确。

任务3(选做):在Linux环境下,可以调用库函数gettimeofday测量一个代码段的执行时间,请写一个程序task43.c,测量read、write、fread、fwrite函数调用所需的执行时间,并与prof/gprof工具测的结果进行对比,看是否基本一致。并对四个函数的运行时间进行对比分析。

提示:由于一次函数调用时间太短,测量误差太多,应测量上述函数多次(如10000次)运行的时间,结果才会准确。

附录:使用prof/gprof测量程序运行时间

Linux/Unix环境提供了prof/gprof工具来收集一个程序各函数的执行次数和占用CPU时间等统计信息,使用prof/gprof工具查找程序性能问题,要求编译命令添加-p选项(prof)或-pg选项(gprof),程序执行时就会产生执行跟踪文件mon.out(或gmon.out),再运行prof(或gprof)程序读取跟踪数据,产生运行报告。现在用gprof对以下程序各函数运行性能(占用CPU时间)进行测量。先输入程序源代码:

$ cat  multiply.c

#include <stdio.h>

int fast_multiply(x,  y)

{

    return x * y;

}

int slow_multiply(x, y)

{

    int i, j, z;

    for (i = 0, z = 0; i < x; i++)

        z = z + y;

    return z;

}

int main(int argc, char *argv[])

{

    int i,j;

    int x,y;

    for (i = 0; i < 2000; i ++) {

        for (j = 0; j <  3000 ; j++) {

            x = fast_multiply(i, j);

            y = slow_multiply(i, j);

        }

    }

    printf("x=%d, y=%d\n", x, y);

    return 0;

}

然后编译和执行该程序,检查是否函数性能跟踪数据文件gmon.out:

$ gcc  -pg  -o  multiply multiply.c   -g

$ ./multiply

x=5995001, y=5995001

$ ls gmon.out

gmon.out

最后,用gprof命令产看各函数执行时间:

$ gprof multiply gmon.out

Flat profile:

Each sample counts as 0.01 seconds.

  %    cumulative  self                 self     total           

 time   seconds    seconds   calls        us/call   us/call  name    

 99.44    14.11    14.11     6000000     2.35    2.35    slow_multiply

 0.42     14.17    0.06                                 main

  0.14     14.19    0.02      6000000      0.00    0.00   fast_multiply

在这里,slow_multipy和fast_multiply执行600000次所花运行时间为14.11s和0.02秒。

任务4(选做):在Linux系统环境下,编写程序task44.c,对一篇英文文章文件的英文单词词频进行统计。

  1. 以“单词:次数”格式输出所有单词的词频
  2. 以“单词:次数”格式、按词典序输出各单词的词频
  3. 以“单词:次数”格式输出出现频度最高的10个单词的词频

例如,若某个输入文件内容为:

     GNU is an operating system that is free software—that is, it respects users' freedom.

The development of GNU made it possible to use a computer without software that would trample your freedom.

则输出应该是:

      GNU:2

      is:3

      it:2

      ……

提示:可以调用字符串处理函数、二叉树处理函数等库函数

三、涉及实验的相关情况介绍(包含使用软件或实验设备等情况):

   安装Linux操作系统的计算机

四、报告内容(给出每个任务的要求、设计思想、源代码,后接编译过程、测试数据与运行结果截图)

(1)

先创建一个子目录:mkdir 文件名;再在子目录下创建一个.c文件一个.txt文件:touch student.txt  touch task41.c;向文件中写入内容:cat>文件名 ;查看文件内容:cat 文件名

源代码:

(1)、
#include<stdio.h>
#include<string.h>
#define MAXSIZE 200
void main()
{
FILE* fp1, * fp2;
char buf[MAXSIZE];
char* a[6];
char buffer[100];
char check[] = "计算机与网络安全学院";
char s[2]=":";
if ((fp1 = fopen("student.txt", "r")) == NULL)
{
printf(" Open Failed!");
//return 0;
}
if ((fp2 = fopen("csStudent.txt", "a+")) == NULL)
{
printf(" Open Failed!");
//return 0;
}
while (!feof(fp1))//文本结束时退出循环
{
fgets(buf, MAXSIZE, fp1);//一行行读入
if (strstr(buf, check))//判断是否属于“计算机与网络安全学院”
{
a[0] = strtok(buf, s);//切割字符串成五部分
a[1] = strtok(NULL, s);
a[2] = strtok(NULL, s);
a[3] = strtok(NULL, s);
a[4] = strtok(NULL, s);
a[4][3] = 0;//将换行符去掉
sprintf(buffer, "%s:%s:%s:%s:%s\n", a[1], a[0], a[3], a[4], a[2]);//格式化写入buffer
fputs(buffer, fp2);//将buffer写入文本csStudent
}
}
fclose(fp1);
fclose(fp2);
//return 0;
}

编译过程:

gcc task41.c -o task41

./task41

查看csStudent.txt文件内容:cat csStudent.txt

测试数据:

运行结果:

放截图

运行结果:

放截图

(2)、

    源代码:

#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;

void main(){

  subject su1[5];

  subject as;

  int i;

  int fd;

  fd=open("data",O_WRONLY|O_CREAT|O_TRUNC,0777);

  for(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(i = 0;i < 5;i ++)

    read(fd,(void*)&su1[i],sizeof(subject));

  for(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);

  }

编译过程:

gcc task42.c -o task42

./task42

源代码:

#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);

}

编译过程:

gcc task43.c -o task43

./task43

运行结果:

放截图

源代码:

#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]);

        }

编译过程:

gcc tasks44.c -o task44

./task44

测试数据:

放截图

运行结果:

放截图

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值