20191205张潇——MyOD(选做作业)
二、编写myod.c
1.用myod XXX实现Linux下od -tx -tc XXX的功能
首先新建一个文件夹(myod)——由于我已经完成,所以文件里已经有了ascii.c、head.h、hex.c、myod.c等文件
随后在myod里新建一个test.txt文本文件,里输入了我的学号20191205还有些其他的随机数
实验代码截图:
hex.c文件(代码链接:https://gitee.com/two_thousand_and_thirteen/codes/q3w4yxslv8kz0gb2chjm651)
#include <stdio.h> #include "head.h" void hex(char *name) { FILE *fp; char ch; printf("output hex:\n"); fp=fopen(name,"r"); ch=fgetc(fp); while(ch!=EOF) { if(ch=='\n') printf("\n"); else printf("%4x",ch); ch=fgetc(fp); } fclose(fp); }
ascii.c文件(代码链接:https://gitee.com/two_thousand_and_thirteen/codes/m9twubicljsadn7yp142085)
#include <stdio.h> #include "head.h" void ascii(char *name) { FILE *fp; char ch; fp=fopen(name,"r"); ch=fgetc(fp); printf("output ascii:\n"); while(ch!=EOF) { if(ch=='\n') printf("\n"); else printf("%4d",ch); ch=fgetc(fp); } fclose(fp); }
head.h文件
myod.c文件(代码链接:https://gitee.com/two_thousand_and_thirteen/codes/ju1ypagfot6c4slbhe92726)
#include <stdio.h> #include "head.h" void main() { char name[50]; printf("please input name:"); scanf("%s",name); ascii(name); hex(name); }
test.txt文件
代码编译&&运行结果:
三、制作静态库、动态库以及编写makefile
1.制作静态库
gcc -c ascii.c -o ascii.o gcc -c hex.c -o hex.o ar cr myod.a *.o gcc -o myod myod.c -L. myod.a
2.制作动态库
gcc -shared -fpic -o myod.so hex.c ascii.c gcc myod.c myod.so export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
3.编写makefile
编写add.c文件
#include "test.h"
#include <stdio.h>
int add(int a, int b)
{
return a + b;
}
int main()
{
printf(" 2 + 3 = %d\n", add(2, 3));
printf(" 5 - 3 = %d\n", sub(5, 3));
return 1;
}
编写sub.c文件
#include "test.h" int sub(int a, int b) { return a - b; }
编写test.h文件
#ifndef _TEST_H #define _TEST_H int add(int a, int b); int sub(int a, int b); #endif
编写makefile文件
test:add.o sub.o gcc -o test add.o sub.o add.o:add.c test.h gcc -c add.c sub.o:sub.c test.h gcc -c sub.c clean: rm-rf test rm-rf *.o
最后编译运行直接make即可
表示成功,ls一下会发现多了两个.o文件和一个可执行的test文件,然后执行
2+3=5
5-2=3
makefile编译成功
四、问题与解决过程
1.对于c文件处理内容有些不太熟悉了,后来通过查阅相关资料,找到了一些比较全面的c文件处理内容如下:
一、文件的打开与关闭
1、fopen FILE *fopen( const char *filename, const char *mode );
说明:
(1)使用文件方式主要有:只读(r)、只写(w)、追加(a),还有配合"+"使用的方式,如r+、w+、a+;
(2)默认打开的文件为文本文件,用't'表示,可以省略。如果打开二进制的文件,则使用'b'。例如:r、rt、rb等;
(3)如果不能实现打开的任务,则函数返回NULL值。
2、fclose int fclose( FILE *stream );
说明:
(1)打开文件后,必须要养成关闭文件的好习惯;
(2)如果关闭文件出错,函数返回非零值,否则返回0.可以用ferror函数检查是否出错。
二、文件的读写
1、fputc
说明:
(1)fputc向文件写入一个字符;
(2)输出成功则返回值就是输出的字符,如果失败则返回一个EOF。
2、fgetc
说明:
(1)fgetc向文件读取一个字符;
(2)函数返回读取的字符,如果遇到文件结尾,则返回EOF;
(3)建议使用feof函数来判断是否文件结束。如果文件结束,函数feof返回值为1,否则为0。
三、文件指针定位
1. rewind void rewind( FILE *stream );
说明:
(1)rewind使文件的位置指针重新定位于文件开头。
2. fseek int fseek( FILE *stream, long offset, int origin );
说明:
(1)起始点用0、1、2代替,分别表示文件开始SEEK_SET、文件当前位置SEEK_CUR、文件末尾SEEK_END;
(2)位移量指起始点为基点,向前移动的字节数。一般为long型;
(3)fseek常用二进制文件,可以实现随机读写。
3. ftell long ftell( FILE *stream );
说明:
(1)函数返回文件当前位置,如果调用出错则返回值为-1L。
四、出错的检测
1、ferror int ferror( FILE *stream );
说明:
(1)返回值为0,表示未出错,返回值为1,表示出错;
(2)同一个文件每一次调用输入输出函数,均产生一个新 的ferror函数值;
(3)在执行fopen函数时,ferror函数的初始值自动置为0。
2、clearerr
说明:
(1)使文件错误标志和文件结束标志为0。
2.我一开始编译makefile时候总是会出现“没有规则可制作目标”的错误,如图:
后来经过同学的帮助,还有CSDN一些大神的解答我解决了:
make 命令假设在Makefile文件中的第一个目标“myapp”是想创建的目标文件。然后它会检查其它的依赖关系,并确定需要一个有一个名为“main.c”的文件。由于并未创建该文件,Makefile文件里也就未说明如何创建该文件,所以make的第一条命令报错。下面来创建“main.c文件并再次重新执行make即可。
后来我又了解了一些关于makefile的拓展知识:
1. Make
make 是 linux 系统的实用程序。它用于管理对于大型程序的自动编译任务,自动决定程序某一部分需要重新编译,并发出编译指令。虽然,我们最常见于 C 语言程序的编译。但是,make 不限于某一特定语言,凡是可以通过 shell 命令来运行编译器的语言都可以使用 make 。除此之外,你甚至可以用 make 描述任何构建任务,这些任务中,文件需要在其依赖的文件发生变动后自动更新。
2. Makefile
在使用 make 之前,必须要在当前目录下添加一个 Makefile 文件,它描述了文件之间的依赖(输入输出)关系,并提供更新文件的 Shell 命令。Makefile 文件名可以是 Makefile 也可以是 makefile ,推荐使用 Makefile。