导语

  • 自编od C语言实现版名为myod

  • 上个星期有一个初代版,链接- myod原版

  • 这星期的课上要求实现myod-系统调用版本,要求如下

    1 参考教材第十章内容

    2 用Linux IO相关系统调用编写myod.c 用myod XXX实现Linux下od -tx -tc XXX的功能,注意XXX是文件名,通过命令行传入,不要让用户输入文件名

    3.不要把代码都写入main函数中

    4.要分模块,不要把代码都写入一个.c中

    5 提交测试代码和运行结果截图, 提交调试过程截图,要全屏,包含自己的学号信息

程序思路

结构

  • 判定命令行输入是否正确,错误则报错退出。

  • 对文件进行录入并存入字符数组str[]

    相关函数及头文件

函数 头文件
open() #include <sys/types.h>;#include <sys/stat.h>;#include <fcntl.h>
read() #include <unistd.h>
  • 输出八位表示的累计字符
  • 输出最多十六个为一组的文本
  • 输出该组文本各字符的ASCII码
  • 对于每行最多处理16个字符,我使用的是for循环和一个计数函数count共同把控

变量说明

char str[BUFFERSIZE];存整个文本的字符串

int LJ;已累计表示了多少各字符

int SY;还剩下多少字符没有表示

int tSY,Dan;tSY其实是SY,但是为了分模块处理便于我自己的理解便改了个名称,Dan是单次表示字符个数,和tSY组合使用

int tx[8];char tx2[8];用于表示八位十六进制累计数字和ASCII码十六进制表示

补充知识点

优化过程

代码对比

嫌弃版

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
void One(int LJ,int tx[],char tx2[]);
void TX(int H,int tx[]);
char Change(int t);
void main(int argc,char *argv[])
{
FILE *fp;
if((fp = fopen(argv[4],"r")) == NULL)
{
printf(" ***文件打开失败***");
exit(0);
}
if(strcmp(argv[1], "od")==0)
{ if(strcmp(argv[2], "-tc")==0)
{ if(strcmp(argv[3], "-tx")==0)
{
char str[1000];
int num,i,j,i2;
for(num=0; num<strlen(str); num++)str[num] = '0';
num = 0;
int fd;
fd = open(argv[4], O_RDONLY);
num = read(fd, str, sizeof(str));
close(fd); int LJ;
int SY; for(LJ = 0,SY = num;;)
{
int tx[8];
char tx2[8];
for(j=0; j<8; j++)tx[j] = 0;
One(LJ,tx,tx2);
for(j=0; j<8; j++)
{
printf("%c",tx2[j]);
}
printf(" "); //累计字符输出完毕 int tSY,Dan;
tSY = SY;
// do
// {
if(tSY>=16)
{
Dan = 16;
}
else
{
Dan = tSY;
}
for(j=LJ; j<Dan+LJ; j++)
{
// printf("j = %d,Dan=%d\n",j,Dan);
if(str[j]=='\n')
{
printf("\\n ");
}
else
{
printf("%c \t",str[j]);
}
}
// putchar(str[i]);
printf("\n");
int tt;
//输出文本
printf(" ");
for(j=LJ; j<Dan+LJ; j++)
{
tt = str[j];
One(tt,tx,tx2);
for(i2=0; i2<8; i2++)
{
if(tx2[i2]!='0')printf("%c",tx2[i2]);
}
printf(" \t");
}
printf("\n");
tSY = tSY-Dan;
// }
// while(tSY>0);
printf("\n");
// printf("SY=%d,LJ=%d\n",SY,LJ);
if(SY>=16)
{
LJ = LJ+16;
}
else if((SY>0)&&(SY<16))
{
LJ = LJ+SY;
}
else if(SY==0)
{
break;
}
SY = num-LJ;
// printf("SY=%d,LJ=%d\n",SY,LJ);
}
}
}
}
else
{
printf("指令输入错误\n");
}
// printf("\nover\n");
fclose(fp);
}
void One(int LJ,int tx[],char tx2[]) {
TX(LJ,tx);
int i;
// printf("\n分界线\n");
for(i=0; i<8; i++)
{
// printf("%d ",tx[i]);
tx2[i] = Change(tx[i]);
// printf("%c",tx2[i]);
}
}
void TX(int H,int tx[])
{
if(H>536870911)
{
printf("字符数太大,超出限制\n");
exit (0);
}
int i=7;
// printf("LS = %d\n",H);
for(; i>0;)
{
tx[i] = H%16;
H = H/16;
i--;
// printf(" H = %d,tx[%d] = %d\n",H,i+1,tx[i+1]);
}
}
char Change(int t)
{
// printf("scs\n");
if((t>=0)&&(t<10))
{
return t+48;
}
else
{
return t+87;
}
}

优化版

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#define BUFFERSIZE 1000
void Change(int LJ,int tx[],char tx2[]);
void dToH(int H,int tx[]);
char intToChar(int t);
int count(int *tSY,int *Dan,int *LJ,int *SY,int *num);
void outputAscii(char tx2[],int Dan,int LJ,int tx[],char str[]);
void main(int argc,char *argv[])
{
char str[BUFFERSIZE];
int num,i,j,i2;
int fd;
if((strcmp(argv[1], "od")!=0)|(strcmp(argv[3], "-tc")!=0)|(strcmp(argv[2], "-tx")!=0))
{
printf("输入格式错误");
exit(0);
} for(num=0; num<strlen(str); num++)str[num] = '0';
num = 0; if ( (fd = open(argv[4], O_RDONLY)) == -1 )
{
perror(argv[4]);
exit(1);
}
num = read(fd, str, BUFFERSIZE);
close(fd);
int LJ;
int SY;
int tx[8];
char tx2[8];
int tSY,Dan;
for(LJ = 0,SY = num;;)
{ for(j=0; j<8; j++)tx[j] = 0;
Change(LJ,tx,tx2);
for(j=0; j<8; j++)
{
printf("%c",tx2[j]);
}
printf(" "); //累计字符输出完毕 tSY = SY;
if(tSY>=16)
{
Dan = 16;
}
else
{
Dan = tSY;
}
for(j=LJ; j<Dan+LJ; j++)
{
if(str[j]=='\n')
{
printf("\\n ");
}
else
{
printf("%c \t",str[j]);
}
}
printf("\n"); //输出文本
outputAscii(tx2,Dan,LJ,tx,str); if(2==count(&tSY,&Dan,&LJ,&SY,&num))exit(0);
}
}
void Change(int LJ,int tx[],char tx2[]) {
dToH(LJ,tx);
int i;
for(i=0; i<8; i++)
{
tx2[i] = intToChar(tx[i]);
}
}
void dToH(int H,int tx[])//十进制转十六进制,但此时仍用int存储
{
if(H>536870911)
{
printf("字符数太大,超出限制\n");
exit (0);
}
int i=7;
for(; i>0;)
{
tx[i] = H%16;
H = H/16;
i--;
}
}
char intToChar(int t)//十六进制,把int[]转为char[]
{
if((t>=0)&&(t<10))
{
return t+48;
}
else
{
return t+87;
}
}
int count(int *tSY,int *Dan,int *LJ,int *SY,int *num)//计数并判定是否终止
{
*tSY = *tSY-*Dan;
printf("\n");
if(*SY>=16)
{
*LJ = *LJ+16;
}
else if((*SY>0)&&(*SY<16))
{
*LJ = *LJ+*SY;
}
else if(*SY==0)
{
return 2;
}
*SY = *num-*LJ;
return 1;
}
void outputAscii(char tx2[],int Dan,int LJ,int tx[],char str[])
{
int tt,j,i2;
printf(" ");
for(j=LJ; j<Dan+LJ; j++)
{
tt = str[j];
Change(tt,tx,tx2);
for(i2=0; i2<8; i2++)
{
if(tx2[i2]!='0')break;
}
for(;i2<8;i2++)printf("%c",tx2[i2]);
printf(" \t");
}
printf("\n");
}

改造过程

1.把没来得及删掉的用指针打开文件的那段fp = fopen(argv[4],"r"等删掉,有open就可以了

2.修改自编函数名称。当我回来再看代码时原先的名称确实无法提醒我到底它要做什么,(捂脸),所以组合型名称按照小驼峰式,单个词函数名用了首字母大写的方式,多谢老师指导与提醒~

3.判定命令行输入条件时取消那么多if,直接用“|”符号来限定选择条件

 if((strcmp(argv[1], "od")!=0)|(strcmp(argv[3], "-tc")!=0)|(strcmp(argv[2], "-tx")!=0))

4.将存文本的字符大小用宏定义BUFFERSIZE,提高程序的可读性与可维护性。解释:比如我想存一个10000的文本,但是之前的str[]只有1000,所以我只需要把define那里的BUFFERSIZE改掉,后面的就不用改了,否则还得满篇找1000改10000,这个程序短,所以还不觉得有什么,但是程序如果很大很复杂,这种情况不仅维护的人不好读懂代码,而且容易改漏。

5.使用perror()函数,添加报错功能。

6.将计数和输出ASCII码的功能从主函数中分离出来成为自编函数,使主程序显得不那么臃肿,更好读懂。

7.修改了一个程序上的错误

for(i2=0; i2<8; i2++)
{
if(tx2[i2]!='0')printf("%c",tx2[i2]);
}

这个输出会把所有0给抹掉,也是优化的时候才发现这个错误(捂脸)

修改为:

for(i2=0; i2<8; i2++)
{
if(tx2[i2]!='0')break;
}
for(;i2<8;i2++)printf("%c",tx2[i2]);

代码链接

myod嫌弃版(合体)

myod优化版(合体)

myod优化版(模块化)

一阵瞎逼逼

第一个版本我本来就实现了命令行调用,并且并未只写在一个main函数里,就只需要改两个函数就可以了。当时课上电脑不知道被我改了哪里,找不到网络的开关……慌慌地改了代码交了,觉得代码还是有点丑,想着怎么再改改,眼瞎也没看到还有展开项-提交代码……

看到老师对之前博客的评论,越看我的代码越觉得……好嫌弃,确实需要好好改一改。于是真的有不少地方可以改……就有了对二代版的优化版。

之所以单开一篇博客是为了方便我日后记不到了好查找资料。是的,作为一个暑假之后就忘了放在学校电脑的开机密码的人真的不能对自己的记忆力多有信心。以后可能会在自己的博客里记录一些非常简单的知识。反正最终都会忘掉的,不如让再次自学的时候能轻松高效一些。

对Linux命令od -tc -tx1的C语言程序实现myod-优化版的更多相关文章

  1. 课后练习:C语言实现Linux命令——od

    课后练习:C语言实现Linux命令--od --------CONTENTS-------- 题目详情与分析 设计思路 遇到的问题及解决 待实现的设想与思考 学习反思与感悟 附1:myod.c「1.0 ...

  2. C语言实现Linux命令——od

    C语言实现Linux命令--od 实现要求: 复习c文件处理内容 编写myod.c 用myod XXX实现Linux下od -tx -tc XXX的功能 main与其他分开,制作静态库和动态库 编写M ...

  3. Linux命令——od

    参考:Linux OD Command Tutorial for Beginners (6 Examples) 简介 查看普通文本文件,可以使用cat.head.tail.tac.less.more等 ...

  4. Linux命令应用大词典-第12章 程序编译

    12.1 gcc:GNU项目的C和C++编译器 12.2 gdberver:为GNU调试的远程服务器 12.3 cmake:跨平台的Makefile生成工具 12.4 indent:更改通过插入或删除 ...

  5. linux命令中的“<”和“|”是什么意思?

    ”<” 表示的是输入重定向的意思,就是把<后面跟的文件取代键盘作为新的输入设备.”| ”则表示一个管道的意思,可以理解为东西从管道的一边流向另外一边.   cat file.json | ...

  6. 学号20175313 《实现Linux下od -tx -tc XXX的功能》第九周

    目录 MyOD 一.题目要求 二.题目理解 三.需求分析 四.设计思路 五.代码链接 六.代码实现过程中遇到的问题 七.运行结果截图 八.参考资料 MyOD 一.题目要求 编写MyOD.java 用j ...

  7. 实现Linux下od -tx -tc XXX的功能

    实现Linux下od -tx -tc XXX的功能 一.od命令 (1)功能 od命令用于将指定文件内容以八进制.十进制.十六进制.浮点格式或ASCII编码字符方式显示,通常用于显示或查看文件中不能直 ...

  8. 以二进制的形式查看文件 Linux之od命令详解

    od命令 以二进制的形式查看文件 od -t x1 /usr/local/FT/config/hsm_create.utf8.sql ef bb bf 4c 5f 0d 0a 5f 4e 4e 4f ...

  9. [转]Linux之od命令

    转自:http://os.51cto.com/art/200912/173136.htm 随着计算机飞速的发展,很多人开始学习Linux,怎样才能学好Linux,一定要学好Linux的命令.学习Lin ...

随机推荐

  1. pip install lxml mysql-python error

    问题0: 在安装 mysql-python时,会出现: sh: mysql_config: not found Traceback (most recent call last): File &quo ...

  2. jq弹框 (1)内容自适应宽度 2(内容框显示,几秒后自动消失)

      <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&q ...

  3. URAL-1018 Binary Apple Tree---树形DP

    题目链接: https://cn.vjudge.net/problem/URAL-1018 题目大意: 给你一棵树,每条边有一个边权,求以1为根节点,q条边的子数(q+1个点),边权和至最大. 解题思 ...

  4. TensorFlow函数(二)tf.get_variable() 和 tf.Variable()

    tf.Variable(<initial - value>,name=<optional - name>) 此函数用于定义图变量.生成一个初始值为initial - value ...

  5. 第一篇markdown笔记

    博客的样式设置 1 2 3 参考第一篇博客 参考第二篇博客 高效的写博客 博客园虽然支持markdown,但是好多快捷键都不支持,以后可以先在马克飞象上写好markdown笔记,再复制到博客上.

  6. Odoo字段类型

    转载请注明原文地址:https://www.cnblogs.com/cnodoo/p/9278620.html    一:基本字段类型 Binary:二进制类型,用于保存图片.视频.文件.附件等,在视 ...

  7. C++ —— 小操作

    判断一个浮点数是否是整数: #include <iostream> using namespace std; int main() { ); if (l == (int)l) { //.. ...

  8. 【nodejs】创建第一个应用

    我已经安装好了nodejs(采用安装包的方式),并在idea中安装好nodejs插件,具体参考我的随笔: http://www.cnblogs.com/yujihang/p/7011356.html ...

  9. 全球参考系统(WRS)概述及常用工具汇总

    1.全球参考系统(WRS)简介 WRS(Worldwide Reference System)是Landsat卫星采用的全球参考系统,也是国际上非常具有代表意义的全球参考系统之一.WRS是依据卫星地面 ...

  10. SpringBoot+MyBatis中自动根据@Table注解和@Column注解生成ResultMap

    其实我一点都不想用mybatis,好多地方得自己写,比如这里. 使用mybatis要写大量的xml,烦的一批.最烦人的莫过于写各种resultmap,就是数据库字段和实体属性做映射.我认为这里应该是m ...