2020-2021-1 20209326 《Linux内核原理与分析》第二周作业 MyOD(选作)

任务详情

复习c文件处理内容
编写myod.c 用myod XXX实现Linux下od -tx -tc XXX的功能
main与其他分开,制作静态库和动态库
编写Makefile
提交测试代码和运行结果截图, 提交调试过程截图,要全屏,包含自己的学号信息
在博客园发表一篇博客,重点写遇到的问题和解决过程

Linux od命令

Linux od命令用于输出文件内容。
od指令会读取所给予的文件的内容,并将其内容以八进制字码呈现出来。

语法

od [-abcdfhilovx][-A <字码基数>][-j <字符数目>][-N <字符数目>][-s <字符串字符数>][-t <输出格式>][-w <每列字符数>][--help][--version][文件...]
其中od -tx -tc分别显示对应文件的十六进制和ASCII编码字符

实验代码

参照往届学长的程序设计改进代码如下:


问题与改进

1.od命令输出行前有序号,7位,填充0:
解决方法:定义一个计数变量,以printf("%07d ",k);输出。
2.od可以输出'\n'、'\r'、'\t'等转义字符:
解决方法:if判断后再转义输出

                                if(str[j]=='\n'){
					printf(" \\n ");
				}else if(str[j]=='\t'){
					printf(" \\t ");
				}else if(str[j]=='\r'){
					printf(" \\r ");
				}else{
					printf("%4c",str[j]);
				}

3.linux中od命令输出4个的16进制数与ASCII码值相反:
解决办法:逆序输出

                        for(j=0;j<16;j++){
				if((j+1)%4==0){
					printf("%02x%02x%02x%02x         ",str[j],str[j-1],str[j-2],str[j-3]);
				}
			}

4.最后一行输出的格式与od有差异:
解决办法:逐层输出

        printf("%07d      ",k);
	for(j=0;j<i;j++){
		if((j+1)%4==0){
			printf("%02x%02x%02x%02x         ",str[j],str[j-1],str[j-2],str[j-3]);
		} 
	}
	if((j+1)%4==0){
		printf("00%02x%02x%02x         ",str[j],str[j-1],str[j-2]);
	}else if((j+2)%4==0){
		printf("0000%02x%02x         ",str[j],str[j-1]);
	}else if(j%3==0){
		printf("000000%02x         ",str[j]);
	}
	printf("\n");
	printf("	");
	for(j=0;j<i;j++){
		if(str[j]=='\n'){
			printf(" \\n ");
		}else if(str[j]=='\t'){
			printf(" \\t ");
		}else if(str[j]=='\r'){
			printf(" \\r ");
		}else{
			printf("%4c",str[j]);
		}
	}
	printf("\n%07d      \n",k+i%16);

makefile

makefile文件

make过程

实验结果


修改后分模块代码

20209326_myod.c

#include "od.h"

int main(int argc,char *argv[])
{
	od(argv);
	return 0;
}

od.c

#include "od.h"

void od(char *argv[]){	//od函数
	FILE *fp;
	char ch;
	char str[16];
    int i=0;
	int k=0;
	if((fp = fopen(argv[1],"r"))==NULL)
	{
		printf("Failure to open %s !\n",argv[0]);
		exit(0);
	}
	while((ch=fgetc(fp))!=EOF)
	{
		str[i]=ch;
		i++;
		if(i==16)
		{
			i=0;
			printf("%07d      ",k);
			k+=20;
			pm16(str);
		}
	}
	printf("%07d      ",k);
	pml(str,i);
	printf("\n%07d      \n",k+i%16);
	fclose(fp);
}

void pm16(char str[16]){	//处理字符个数能整除16的行的输出
	int j;
	for(j=0;j<16;j++){
		if((j+1)%4==0){
			printf("%02x%02x%02x%02x         ",str[j],str[j-1],str[j-2],str[j-3]);
		}
	}
	printf("\n");
	printf("	");
	for(j=0;j<16;j++){
		prc(str[j]);
	}
	printf("\n");
}

void pml(char str[16],int i){	//处理最后一行的输出
	int j;
	for(j=0;j<i;j++){
		if((j+1)%4==0){
			printf("%02x%02x%02x%02x         ",str[j],str[j-1],str[j-2],str[j-3]);
		} 
	}
	if((j+1)%4==0){
		printf("00%02x%02x%02x         ",str[j],str[j-1],str[j-2]);
	}else if((j+2)%4==0){
		printf("0000%02x%02x         ",str[j],str[j-1]);
	}else if((j+3)%4==0){
		printf("000000%02x         ",str[j]);
	}
	printf("\n");
	printf("	");
	for(j=0;j<i;j++){
		prc(str[j]);
	}
}

void prc(char ch){			//处理输出字符串
	if(ch=='\n'){
		printf(" \\n ");
	}else if(ch=='\t'){
		printf(" \\t ");
	}else if(ch=='\r'){
		printf(" \\r ");
	}else{
		printf("%4c",ch);
	}
}

od.h

#ifndef OD_H
#define OD_H

#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>

void prc(char ch);
void od(char *argv[]);
void pm16(char str[16]);
void pml(char str[16],int i);

#endif

makefile

#变量定义
TARGET=myod
CC=gcc
#把不同的路径赋给相应的变量
DIR_BIN=./bin
DIR_SRC=./src
DIR_INC=./include
DIR_LIB=./lib
#把./src中的所有.c文件拿出来赋给变量SRC_PATH,包括.c文件的路径
SRC_PATH=$(wildcard ${DIR_SRC}/*.c)

#去掉SRC的路径,然后把所有.c文件后缀名,改为.o,最后把这些.o文件赋给变量
OBJ = $(patsubst %.c,%.o,$(notdir ${SRC_PATH}))

#把bin文件夹下的所有.o文件赋给变量
OBJ_PATH=$(wildcard ${DIR_BIN}/*.o)

${TARGET}:${OBJ}
        ${CC} -o ${TARGET} ${OBJ_PATH}
        mv ${TARGET} ${DIR_BIN}/

${OBJ}:
        ${CC} -c ${SRC_PATH} -I ${DIR_INC}
        mv  ${OBJ} ${DIR_BIN}/
        ar rcvs libmyod.a ${DIR_BIN}/*.o
        ${CC} -shared -o libmyod.so ${DIR_BIN}/*.o
        mv libmyod.a ${DIR_LIB}/
        mv libmyod.so ${DIR_LIB}/

编译与结果如下图所示

posted @ 2020-10-18 12:27  20209326  阅读(124)  评论(7编辑  收藏  举报