目录


一、要求

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

二、设计流程

1. 需求分析

执行 od -tx -tc 1.txt 的命令显示如下:

[yogile@yogile-pc MyOD]$ od -tx -tc 1.txt
0000000 0a333231 0a333231 34340a0a 0a343434
1 2 3 \n 1 2 3 \n \n \n 4 4 4 4 4 \n
0000020 32330a0a 34323334 32330a32 34323334
\n \n 3 2 4 3 2 4 2 \n 3 2 4 3 2 4
0000040 0000000a
\n
0000041
  1. 每两行要求显示目标文件的16个字符的对应信息:
  2. 第一行以每四个字节为一组,依次输出四次,并按照小端法形式输出显示;
  3. 第二行按序输出这16个字符,每一个十六进制4字节数组的最后一位,对应下第二行四字符一组的最后一位;
  4. 每要输出一组16字符信息,在开头输出该16字符第一个字符所占的字节序号,文件输出结束时显示最后一字符的字节序列;
  5. 当文件输出到最后几个字节,不满足16个字符一组时,按照16字符组标准输出,其中若4个4字符组中的一个组没有字符,则不显示。
  6. 通过命令行参数,调用文件相关命令,实现读取文件。

2. 概要设计

  • (1) main.c 实现文件读取操作,通过循环输出每16字符第一个字符所占的字节序号,积极在循环中调用输出显示函数,最后显示最后一字符的字节序号。

  • (2) tans_0x.c 实现函数 void tans_0x(char char_pl[], int i); 实现对每16字符组输出显示,以每四个字节为一组,依次输出四次,并按照小端法形式输出显示。

  • (3) tans_pr.c 实现函数 void tans_pr(char char_pl[], int i); 按序输出该16字符组,与 tans_0x(); 函数输出对齐。

伪代码

// 头文件
int main(/* 命令行参数 */) {
if (/* 打开文件失败条件*/) {
// 结束程序
}
while(/* 条件 */) {
// 调用tans_0x();
// 调用tans_pr();
}
if (/* 判断文件有字符 */) {
// 输出最后一字符的字节序号
}
else {
// 输出 "0000000"
}
return 0;
} void tans_0x(char char_pl[], int i_n) {
// for循环,将16字符组以每四个字节为一组,按照小端法形式排序
if (/* 4字符组为"00000000"时 */) {
// 不输出
}
else {
// 输出
}
} void tans_0x(char char_pl[], int i_n) {
for (/* i从0到i_n-1*/) {
if (char_pl[i] == '\n') {
printf(" \\n");
}
else {
// 输出字符
}
}
}

3. 详细设计

main.c

main.c

# include
# include
# include "tansp.h" int main(int argc, char *argv[])

{

// 调用命令行参数args[0],实现文件的选择

FILE *fp=NULL;
if ( (fp = fopen(argv[1], "r")) == NULL) {
printf("您输入的文件有误,请重新输入。\n");
exit(0);
}
char ch;
char char_perline[16];
int i=0,j=0,k=0;
int flag_change=0; while( (ch = fgetc(fp)) != EOF )
{
if (i % 16 == 0) {
printf("%07o",16*j);
j++;
}
if (i == 16) {
i=0;
for (k=0; k<16; k++) {
char_perline[k] = '\0';
}
} if (i < 16) {
char_perline[i] = ch;
if (i == 15) {
tans_0x(char_perline, 16);
tans_pr(char_perline, 16);
printf("\n");
}
}
i++;
flag_change++;
}
if (flag_change != 0) {
if (i < 16) {
tans_0x(char_perline, i);
tans_pr(char_perline, i);
printf("\n");
}
printf("%07o\n",16*(j-1)+i);
}
else {
printf("0000000\n");
}
fclose(fp);
return 0;

}

tans_0x.c

tans_0x.c

# include
# include
# include "tansp.h" void tans_0x(char char_pl[], int i_n) {

int i,j;

int i_t=0;

int left_n = i_n % 4;

int have_n = i_n / 4;

char char_temp[16] = {0};

for (i=i_n; i<16; i++) {

char_pl[i] = '\0';

}

for (int i=0; i<4; i++) {

char_temp[4i+3] = char_pl[4i+0];

char_temp[4i+2] = char_pl[4i+1];

char_temp[4i+1] = char_pl[4i+2];

char_temp[4i+0] = char_pl[4i+3];

}

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

printf(" ");

}

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

if (i != 0) {

printf(" ");

}

if (char_temp[4i] == '\0') {

if (char_temp[4
i+1] == '\0') {

if (char_temp[4i+2] == '\0') {

if (char_temp[4
i+3] == '\0') {

// 不输出

break;

}

}

}

}

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

printf("%.2x", char_temp[4*i+j]);

}

}

printf("\n");

}

tans_pr.c

tans_pr.c

# include
# include
# include "tansp.h" void tans_pr(char char_pl[], int i_n) {

int i_t=0;

printf(" ");

for (i_t=0; i_t < i_n; i_t++) {

if (char_pl[i_t] == '\n') {

printf(" \n");

}

else if (char_pl[i_t] == '\0') {

break;

}

else {

printf(" %c", char_pl[i_t]);

}

}

}

tansp.h

tansp.h

#ifndef TANSP_H
#define TANSP_H void tans_pr();

void tans_0x();

endif


三、编写Makefile,并制作动、静态库

Makefile

Makefile

```
# This is a make file.

Generate using static library.

myod:bin/myod

ln -s bin/myod myod

bin/myod:src/main.c libs/libtansp.a

gcc src/main.c libs/libtansp.a -I include/ -o bin/myod

libs/libtansp.a:libs/tans_pr.o libs/tans_0x.o

ar rcvs libs/libtansp.a libs/tans_pr.o libs/tans_0x.o

libs/tans_pr.o:src/tans_pr.c

gcc -c src/tans_pr.c -I include/ -o libs/tans_pr.o

libs/tans_0x.o:src/tans_0x.c

gcc -c src/tans_0x.c -I include/ -o libs/tans_0x.o

Generate using dynamic library.

bin/myod_so:src/main.c libs_so/libtansp.so

gcc src/main.c libs_so/libtansp.so -I include/ -o bin/myod_so

libs_so/libtansp.so:libs_so/tans_pr.o libs_so/tans_0x.o

gcc -shared -o libs_so/libtansp.so libs_so/tans_pr.o libs_so/tans_0x.o

libs_so/tans_pr.o:src/tans_pr.c

gcc -fPIC -c -I include/ src/tans_pr.c -o libs_so/tans_pr.o

libs_so/tans_0x.o:src/tans_0x.c

gcc -fPIC -c -I include/ src/tans_0x.c -o libs_so/tans_0x.o
</code></pre>
</details> 直接使用 `Linux$ make` 默认制作静态库,在5-12行前加 `#` 使用 `Linux$ make` 可制作动态库。 - make 制作静态库:
![](https://img2018.cnblogs.com/blog/1591904/201909/1591904-20190928183451316-1742068637.png) - make 制作动态库:
![](https://img2018.cnblogs.com/blog/1591904/201909/1591904-20190928183439725-1395422407.png) <br> ****
# 四、创建对于 bin/myod 的链接 `Linux$ ln -s bin/myod myod` 在项目文件夹下创建对于 bin/myod 的链接,可直接 `./myod XXX` 运行。
输入 `Linux$ ls -l myod` 可看到:

lrwxrwxrwx 1 yogile yogile 8 9月 28 15:32 myod -> bin/myod


<br> ****
# 五、测试及结果 1. 读取显示 无数据 文本: `./myod byte_txt/byte_0.txt`
2. 读取显示 11 比特文本: `./myod byte_txt/byte_11.txt`
3. 读取显示 16 比特文本: `./myod byte_txt/byte_16.txt`
4. 读取显示 更多数据 文本: `./myod byte_txt/byte_more.txt` ![](https://img2018.cnblogs.com/blog/1591904/201909/1591904-20190928183140184-2127763502.png) <br> ****
# 六、遇到的问题和解决过程 ## 1. 段错误 (核心已转储) 编译链接生成可执行文件时没有问题,但在运行时报错:

[yogile@yogile-pc MyOD]$ ./myod byte_txt/byte_0.txt

段错误 (核心已转储)


- 问题原因分析:
由于在 `main.c` 中的命令行参数输入错误,导致访问不存在的内存地址。

int main(char *argv[]) {

printf("args[1] = %s",argv[1]);

...

}


- 问题解决方法:
输入正确的格式:

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


## 2. 警告:比较指针和整数 为了判定文件的字符是否读完,我想得是没有字符复制给 `char_perline[i]`,其值为空,但报错:

[yogile@yogile-pc M[yogile@yogile-pc src]$ gcc main.c -o main.out

main.c: 在函数‘main’中:

main.c:23:35: 警告:比较指针和整数

23 | for (i=0; char_perline[i] != NULL; i++) {

| ^~

main.c:29:35: 警告:比较指针和整数

29 | for (i=0; char_perline[i] != NULL; i++) {

|


- 问题原因分析:
错误是比较了指针和整数。
实际上,我使用的 while循环的条件是 `(ch = fgetc(fp)) != EOF` 。当文件读完时,循环直接停止,不再赋值给 `char_perline[i]` 。 - 问题解决方法:
在赋值前,将 `char char_perline[]` 的每一项初始化为 `\0` ,`\0` 的16进制编码是 00,`NULL` 改成 `'\0'` 。 ## 3. 警告:隐式声明函数

[yogile@yogile-pc MyOD]$ make

gcc src/main.c libs/libtansp.a -I include/ -o bin/myod

src/main.c: 在函数‘main’中:

src/main.c:29:17: 警告:隐式声明函数‘tans_0x’ [-Wimplicit-function-declaration]

29 | tans_0x(char_perline, 16);

| ^~~~~~~


- 问题原因分析:
缺少声明 `tans_0x()` 函数的头文件。 - 问题解决方法:
添加声明 `tans_0x()` 函数的头文件:`# include "tansp.h"` 。 ## 4. 读取无字符或字符数小于16个的文件,输出乱码。

[yogile@yogile-pc MyOD]$ ./myod byte_txt/byte_0.txt

7dffffffeb6750 0000563f 7dffffffeb60ffffffa0 0000563f

37777777760

[yogile@yogile-pc MyOD]$ ./myod byte_txt/byte_11.txt

000000 34333231 38373635 5f0a6139 00005633

1 2 3 4 5 6 7 8 9 a \n

000013


- 问题原因分析:

int main(/* 命令行参数 /) {

if (/
打开文件失败条件/) {

// 结束程序

}

while(/
条件 */) {

// 调用tans_0x();

// 调用tans_pr();

}

// 输出最后一字符的字节序号

return 0;

}

其中第 9 行 `// 输出最后一字符的字节序号` ,在实际调用中 `tans_0x(char_perline, 16);` 向函数中传递了16个字节数据,但实际数据字符并没有16个字节。所以输出时输出没赋值的 `char_perline[i]` 时,输出乱码。
- 问题解决方法:
添加变量 `flag_change = 0` ,只要while语句运行,就 `flag_change++`。添加 if 语句,进行判断剔除。

if (flag_change != 0) {

if (i < 16) {

tans_0x(char_perline, i);

tans_pr(char_perline, i);

printf("\n");

}

printf("%07o\n",16*(j-1)+i);

}

else {

printf("0000000\n");

}


<br> ****
# 七、下载及码云链接
- [MyOD.zip下载](https://files.cnblogs.com/files/Yogile/MyOD.zip)
- 码云链接:https://gitee.com/Yogile/Cpt_System_Yogile/tree/master/week_homework <br> ****
# 八、问题解决参考资料
- [C语言再学习 -- 段错误(核心已转储)](https://blog.csdn.net/qq_29350001/article/details/53780697)

2019-2020-1 20175223 《信息安全系统设计基础》MyOD的更多相关文章

  1. 2017-2018-1 20155326 《信息安全系统设计基础》第四周学习总结及myod改进版的补交

    2017-2018-1 20155326 <信息安全系统设计基础>第四周学习总结及myod改进版的补交 学习内容 补充完成课上没有完成的内容 学习教材附录A,第十章内容 参考别出心裁的Li ...

  2. 20155326 2017-2018-1 《信息安全系统设计基础》第2周学习及课堂总结myod

    20155326 2017-2018-1 <信息安全系统设计基础>第1次学习及课堂总结myod 虚拟机之前出了一些问题,然后我重新弄了一个新的虚拟机. 先在虚拟机里面安装了git. 安完以 ...

  3. 2017-2018-1 20155305 《信息安全系统设计基础》第四周学习总结(课堂提交作业未来得及提交码云链接myod补充博客)

    2017-2018-1 20155305 <信息安全系统设计基础>第四周学习总结(课堂提交作业未来得及提交码云链接myod补充博客) 课堂提交题目要求 编写MyOD.java 用java ...

  4. 2017-2018-1 20155313 《信息安全系统设计基础》 Myod

    2017-2018-1 20155313 <信息安全系统设计基础> Myod Myod要求 1.复习c文件处理内容 2.编写myod.c 用myod XXX实现Linux下od -tx - ...

  5. 20155216 2017-2018-1 《信息安全系统设计基础》第二周课堂练习补交以及Myod的实现

    20155216 2017-2018-1 <信息安全系统设计基础>第二周课堂练习补交 课堂测试3:行断点的设置 运行截图: 未完成原因:课前未安装 cgdb 具体步骤: 1.输入命令:gc ...

  6. 2017-2018-1 20155232 《信息安全系统设计基础》第四周学习总结以及课上myod练习补充博客

    2017-2018-1 20155232 <信息安全系统设计基础>第四周学习总结以及课上myod练习补充博客 课上myod练习 1 参考教材第十章内容 2 用Linux IO相关系统调用编 ...

  7. 2017-2018-1 20155318 《信息安全系统设计基础》第2周课堂实践、makefile、以及myod

    2017-2018-1 20155318 <信息安全系统设计基础>第2周课堂实践.makefile.以及myod 测试3-gdb测试 用gcc -g编译vi输入的代码 在main函数中设置 ...

  8. # 20155337 2017-2018-1 《信息安全系统设计基础》第二周课堂实践+myod

    20155337 2017-2018-1 <信息安全系统设计基础>第二周课堂实践+myod 因为在课上已经提交了四个实验,还欠缺最后一个实验,反省一下自己还是操作不熟练,平时在课下应该多多 ...

  9. 20155308&20155316 2017-2018-1 《信息安全系统设计基础》实验一

    20155308&20155316 2017-2018-1 <信息安全系统设计基础>实验一 此次实验我和黄月同学一起做了1.2.3.5项,第4项在实验课上做完了,但是没有按时提交. ...

  10. 2017-2018-1 20155320 《信息安全系统设计基础》第四周学习总结(课堂实践补交+myhead与mytail加分项目)

    2017-2018-1 20155320 <信息安全系统设计基础>第四周学习总结(课堂实践补交+myhead与mytail实现) 课堂实践内容 1 参考教材第十章内容 2 用Linux I ...

随机推荐

  1. SVG绘制随机的柱形图+php

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

  2. 状压DP : [USACO06NOV]玉米田

    玉米田 内存限制:128 MiB 时间限制:1000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 题目描述 农场主John新买了一块长方形的新牧场,这块牧场被划分成M行N列(1 ≤ M ≤ ...

  3. Using Tensorflow SavedModel Format to Save and Do Predictions

    We are now trying to deploy our Deep Learning model onto Google Cloud. It is required to use Google ...

  4. 应用安全-XXE(XML外部实体注入)攻防整理

    libxml2..1及以后,默认不解析外部实体.测试的时候window下使用php5.(libxml Version ), php5.(libxml Version ).Linux中需要将libxml ...

  5. linux操作系统的调度策略

    linux的进程分为两种 1.实时进程,优先级高,操作系统会优先执行这种进程 2.普通进程,大多数的进程都是这种进程 调度策略 unsigned int policy; 调度策略的定义 #define ...

  6. win10设置python环境变量

    1.点“我的电脑”,右键选“属性” 2.选择“高级系统设置”--->选“环境变量”--->在“系统变量”中选中“Path”,再点“编辑”--->再点“编辑文本”

  7. 微信小程序这一块(中)

    1.if语句跟for循环的使用 <block wx:if="{{n==1}}"> <view>1917</view> </block> ...

  8. pytest--命令行参数

    使用pytest --help可以查看全部选项 ​ -v:pytest -v 说明:可以输出用例更加详细的执行信息,比如用例所在的文件及用例名称等 -q(--quiet) 该选项的作用与-v/--ve ...

  9. jq鼠标移入移除

    ele.on({ mouseover : function(){ } , mouseout : function(){ } })

  10. XMPP即时通讯协议使用(七)——利用Strophe实现WebIM及strophe.plugins插件使用

    Strophe简介与Openfire配置 Strophe.js是为XMPP写的一个js类库.因为http协议本身不能实现持久连接,所以strophe利用BOSH模拟实现持久连接. 官方文档: http ...