UNIX I/O函数进行文件读写编程

任务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,对一篇英文文章文件的英文单词词频进行统计。

  1. 以“单词:次数”格式输出所有单词的词频(必做)
  2. 以“单词:次数”格式、按词典序输出各单词的词频(选做)
  3. 以“单词:次数”格式输出出现频度最高的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]);
}

  • 7
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值