2017-2018-1 20155320 实验三——实时系统

本文介绍了一个基于 Linux 的 wc 命令的自定义实现,包括如何统计文本文件中的行数、单词数和字符数等内容。同时,还探讨了多线程版本的实现及其与单线程版本的性能对比。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2017-2018-1 20155320 实验三——实时系统

实验三-并发程序-1

学习使用Linux命令wc(1)

基于Linux Socket程序设计实现wc(1)服务器(端口号是你学号的>后6位)和客户端

客户端传一个文本文件给服务器
服务器返加文本文件中的单词数

上方提交代码
附件提交测试截图,至少要测试附件中的两个文件

  • 学习使用Linux命令wc(1)

命令格式:wc [选项]文件..

-c 统计字节数。

-l 统计行数。

-m 统计字符数。这个标志不能与 -c 标志一起使用。

-w 统计字数。一个字被定义为由空白、跳格或换行字符分隔的字符串。

-L 打印最长行的长度。

1071521-20171119145519968-1697150292.png

1071521-20171119151311687-144154536.png

我的mywc的实现:

#include<stdio.h>  
#include<unistd.h>  
#include<sys/stat.h>  
#include<stdlib.h>  
struct message{  
        int lines;  
        int words;  
        int max_line_length;  
        int size;  
        int chars;  
}info;  
void error_print(char str[]){  
        printf("Error:%s",str);  
}  
void init(char filename[]){  
        struct stat get_message = {};  
        FILE *fp;  
        int ret_stat = stat(filename,&get_message);/*用stat函数读取filenmae文件的信息,并将结果写到get_message结构体中*/  
        if(ret_stat == -1){//stat函数不出错则进行信息输出  
                error_print(filename);  
                return ;  
        }  
        mode_t mode = get_message.st_mode;      //接收文件信息,用于下面判断是不是目录  
        int length = 0;  
        if(S_ISDIR(mode))   //如果是目录,输出错误  
                printf("Error %s is dir\n0\t0\t0\t%s",filename,filename);  
        else{  
                info.size = get_message.st_size;    //文件字节大小 wc -c  
                fp = fopen(filename,"r");   //以只读方式打开指定文件  
                char ch;  
                int flag = 0;  
                while((ch = fgetc(fp))!=EOF){   //一直读到文件尾  
                        info.chars++;       //字符数加1 wc -m  
  
                        if(ch != '\n'){  
  
                                length++;   //记录当前行的长度 wc -L  
                        }  
                        if(ch == '\n'){  
                                info.lines ++;  //行数加1 wc -l  
                                if(length>info.max_line_length)  
                                        info.max_line_length = length;  //更新最大长度  
                                length = 0;  
                        }  
                        if(ch == '\t' || ch == ' ' || ch == '\n'){  
                                flag = 0;       //计算单词数 wc -w  
                                continue;  
                        }  
                        else{  
  
                                if(flag == 0){  
                                        info.words++;   //计算单词数 wc -w  
                                        flag = 1;  
                                }  
                        }  
                }  
                fclose(fp);  
        }  
  
}  
//计算键盘输入内容的相关信息,即参数中没有指定要打开的文件  
void EmptyFile(){  
        char ch;  
        int flag = 0;  
        int length = 0;  
  
        while((ch = getchar())!=EOF){  
                info.chars++;  
                info.size += sizeof(ch);    //字节累加  
                if(ch != '\n'){  
                        length++;  
                }  
                if(ch == '\n'){  
                        info.lines ++;  
                        if(length>info.max_line_length)  
                                info.max_line_length = length;  
                        length = 0;  
                }  
                if(ch == '\t' || ch == ' ' || ch == '\n'){  
                        flag = 0;  
                        continue;  
                }  
                else{  
  
                        if(flag == 0){  
                                info.words++;  
                                flag = 1;  
                        }  
                }  
  
        }  
}  
int main(int argc,char *argv[]){  
  
        if(argc == 2){  
                if(argv[1][0] != '-'){  
                        init(argv[1]);  
                        printf("%d %d %d %s\n",info.lines,info.words,info.size,argv[1]);  
                        return 0;  
                }  
                else{   //未指定打开文件,类似 wc -lmwcL  
                        EmptyFile();  
  
                }  
        }  
        else if(argc == 1){     //未指定打开文件和要输出的参数,(默认输出 -lwc)  
                EmptyFile();  
                printf("%d\t%d\t%d\n",info.lines,info.words,info.size);  
                return 0;  
        }  
        else if(argc == 3){  
                init(argv[2]);  
        }  
        int num;  
        while((num = getopt(argc,argv,"lwmcL"))!=-1){  
                switch(num){  
                        case 'l':  
                                printf("%d\t",info.lines);  
                                break;  
                        case 'w':  
                                printf("%d\t",info.words);  
                                break;  
                        case 'm':  
                                printf("%d\t",info.chars);  
                                break;  
                        case 'c':  
                                printf("%d\t",info.size);  
                                break;  
                        case 'L':  
                                printf("%d\t",info.max_line_length);  
                                break;  
                }  
        }  
        if(argc != 2 && argv[1][0] != '-')  //一定要判断,否则会越界  
                printf("%s\n",argv[2]);  
  
  
        return 0;  
}  
  • wc的测试
    1071521-20171119173442359-218837871.png

  • 客户端与服务器运行结果截图如下
    1071521-20171119170728577-1878967542.png

实验三-并发程序-2

使用多线程实现wc服务器并使用同步互斥机制保证计数正确

对比单线程版本的性能,并分析原因

  • 运行截图如下:

1071521-20171119180628296-553243524.png

  • 对比单线程版本的性能,并分析原因

    并发的程序相对单线程版本来说最直观的特点就是其可以实现一个服务器连接多个客户端,这是单线程版本无法做到的,可见相较单线程版本来说更加完善

实现中遇到的问题

  • 问题:代码完成后,mywc统计字符数是对的,但是客户端显示的却不对

  • 解决:用cbd调试代码,先不打印,发现用来存储字节的buff数组末尾没有\0,因此不会被看成字符串输出,修改代码后,则运行成功了

转载于:https://www.cnblogs.com/ljq1997/p/7860617.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值