1. 练习open/read/write/close等文件相关系统调用接口,纵向对比fd与FILE结构体
2. 对之前编写的自主shell进行修改,使其支持输入/输出/追加重定向
3. 编写简单的add/sub/mul/div函数,并打包成动/静态库,并分别使用。
1. 练习open/read/write/close等文件相关系统调用接口,纵向对比fd与FILE结构体
1. open的原型是:
int open(const char *filename, int flags, mode_t mode);
第一个参数:是打开文件的路径
第二个参数:是打开的方式
打开方式有以下几种:
O_RDONLY:只读方式打开
O_WRONLY:只写方式打开
O_RDWR:读写方式打开
O_CREAT:若文件不存在则创建这个文件,需要第三个参数,权限
O_APPEND:追加写
O_TRUNC:(打开文件时清空)
第三个参数:是文件权限(可用八进制数字表示)
返回值:返回一个新的文件描述符,若是有错误返回-1。
2. read的函数原型是:
ssize_t read(int fd, void *buf, size_t count);(其中ssize_t是有符号的int)
第一个参数:文件描述符
第二个参数:定义的缓冲区,例如传入一个数组指针
第三个参数:要读入数据的大小
返回值:成功时返回读取到的字节数(为零表示读到文件描述符),此返回值受文件剩余字节数限制,当返回值小于指定的字节数(比如已经接近文件结尾,或者正在从管道或者终端读取数据,或者read()被信号中断),发生错误时返回-1
3. write的函数原型是:
ssize_t write(int fd, void *buf, size_t count);(其中ssize_t是有符号的int)
第一个参数:文件描述符
第二个参数:写入的内容
第三个参数:写入的字节数
返回值:成功时返回写入的字节数(若为零则表示没有写入数据),错误时返回-1。
4. close的函数原型是:
int close(int fd);(其中fd表示文件标识符)
返回值:返回0表示成功,返回-1表示失败
代码:
write: 01open.c:
#include<stdio.h>
#include<string.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
int main()
{
umask(0);
int fd=open("myfile1",O_WRONLY|O_CREAT,0644);//open函数,0644代表权限
if(fd<0){
perror("open");
return 1;
}
int count=5;
const char*msg="hello world\n";
int len=strlen(msg);
while(count--){
write(fd,msg,len+1);
}
close(fd);
return 0;
}
read: 02read.c:
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
int main()
{
int fd;
if( (fd=open("mmc",O_RDWR)) == -1)
perror("open"),exit(1);
char buf[4] = {};
while(1)
{
memset(buf,0x00,sizeof(buf));
int r = read(fd,buf,3);
if(r<=0)
{
break;
}
printf("%s",buf);
fflush(stdout);
sleep(1);
}
close(fd);
}
fd和FILE对比:
fd属于系统库 , FILE属于c标准库;
fd是一个整数,FILE是一个结构体.
2. 对之前编写的自主shell进行修改,使其支持输入/输出/追加重定向
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
int main()
{
close(1);
int fd=open("myfile1",O_WRONLY|O_CREAT,0644);//open函数,0644代表权限
if(fd<0){
perror("open");
return 1;
}
printf("fd:%d",fd);
fflush(stdout);
close(fd);
exit(0);
return 0;
}
扫描二维码关注公众号,回复:
1011343 查看本文章
3. 编写简单的add/sub/mul/div函数,并打包成动/静态库,并分别使用。
静态库:
ar : 归档
libxxx.a :库文件名
(其中xxx是库名)
生成静态库:
① gcc -c xxx.c -o xxx.o
② ar -rc libxxx.a xxx.o xxx.o
③ gcc main.c libxxx.a
//gcc main.c -lxxx
(标准版测试运行:gcc main.c -lxxx -L .)
动态库 (共享库):
生成动态库:
gcc -fPIC -shared -o libxxx.so xxx.c
(其中 -fPIC 是未知无关)
代码:
add.c
#include "add.h"
int add(int a,int b)
{
return a + b;
}
add.h:
#ifndef __ADD_H__
#define __ADD_H__
int add(int a,int b);
#endif /// __ADD_H__
sub.c
#include "sub.h"
int sub(int a,int b)
{
return a - b;
}
sub.h
#ifndef __SUB_H__
#define __SUB_H__
int sub(int a,int b);
#endif /// __SUB_H
mul.c
#include "mul.h"
int mul(int a,int b)
{
return a * b;
}
mul.h
#ifndef __MUL_H__
#define __MUL_H__
int mul(int a,int b);
#endif /// __MUL_H
div.c
#include "div.h"
int div(int a,int b)
{
return a/b;
}
div.h
#ifndef __DIV_H__
#define __DIV_H__
int div(int a,int b);
#endif /// __DIV_H
main.c
#include <stdio.h>
#include "add.h"
#include "sub.h"
#include "mul.h"
#include "div.h"
int main()
{
int a,b;
printf("input a b : ");
scanf("%d %d",&a,&b);
printf(" %d + %d = %d\n",a,b,add(a,b));
printf(" %d - %d = %d\n",a,b,sub(a,b));
printf(" %d * %d = %d\n",a,b,mul(a,b));
printf(" %d / %d = %d\n",a,b,div(a,b));
}
makefile:
.PHONY:libmymath.a clean
libmymath.a:main.o add.o sub.o mul.o div.o
ar -rc $@ $^
%.o : %.c
gcc -c $^ -o $@
clean:
rm -rf *.o
生成静态库:
生成动态库:
直接./a.out有错误,更改一下 LD_LIBRARY_PATH
(方法:export LD_LIBRARY_PATH=.)