IO标准库和系统调用接口_a short item count-程序员宅基地

技术标签: Linux  

标准库接口

fopen/fread/fwrite/fseek/fclose

FILE *fopen(const char *path, const char *mode);
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
int fseek(FILE *stream, long offset, int whence);
int fclose(FILE *stream);

  • FILE *fopen(const char *path, const char *mode);
    #include <stdio.h>

description:
The fopen() function opens the file whose name is the string pointed
to by pathname and associates a stream with it.

The argument mode points to a string beginning with one of the
following sequences (possibly followed by additional characters, as
described below):

made:
r+ Open for reading and writing. The stream is positioned at the
beginning of the file.

w Truncate file to zero length or create text file for writing.
The stream is positioned at the beginning of the file.

w+ Open for reading and writing. The file is created if it does
not exist, otherwise it is truncated. The stream is
positioned at the beginning of the file.

a Open for appending (writing at end of file). The file is
created if it does not exist. The stream is positioned at the
end of the file.

a+ Open for reading and appending (writing at end of file). The
file is created if it does not exist. Output is always
appended to the end of the file. POSIX is silent on what the
initial read position is when using this mode. For glibc, the
initial file position for reading is at the beginning of the
file, but for Android/BSD/MacOS, the initial file position for
reading is at the end of the file.

  • size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
    #include <stdio.h>

description:
The function fread() reads nmemb items of data, each size bytes long,
from the stream pointed to by stream, storing them at the location
given by ptr.
return value:
On success, fread() and fwrite() return the number of items read or
written. This number equals the number of bytes transferred only
when size is 1. If an error occurs, or the end of the file is
reached, the return value is a short item count (or zero).
fread() does not distinguish between end-of-file and error, and
callers must use feof(3) and ferror(3) to determine which occurred.

  • size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
    #include <stdio.h>

description:
The function fwrite() writes nmemb items of data, each size bytes
long, to the stream pointed to by stream, obtaining them from the
location given by ptr.
return value:
On success, fread() and fwrite() return the number of items read or
written. This number equals the number of bytes transferred only
when size is 1. If an error occurs, or the end of the file is
reached, the return value is a short item count (or zero).

  • int fseek(FILE *stream, long offset, int whence);
    #include <stdio.h>

description:
The fseek() function sets the file position indicator for the stream
pointed to by stream. The new position, measured in bytes, is
obtained by adding offset bytes to the position specified by whence.
If whence is set to SEEK_SET, SEEK_CUR, or SEEK_END, the offset is
relative to the start of the file, the current position indicator, or
end-of-file, respectively. A successful call to the fseek() function
clears the end-of-file indicator for the stream and undoes any
effects of the ungetc(3) function on the same stream.
return value:
successful completion,
fgetpos(), fseek(), fsetpos() return 0, and ftell() returns the
current offset. Otherwise, -1 is returned and errno is set to
indicate the error.

  • int fclose(FILE *stream);
    #include <stdio.h>

description:
The fclose() function flushes the stream pointed to by stream
(writing any buffered output data using fflush(3)) and closes the
underlying file descriptor.
return value:
Upon successful completion, 0 is returned. Otherwise, EOF is
returned and errno is set to indicate the error. In either case, any
further access (including another call to fclose()) to the stream
results in undefined behavior.

fgets/printf/sprintf(buffer)/snprintf(buffer)/fprintf(file)

char *fgets(char *restrict s, int n, FILE *restrict stream);
int sprintf(char *restrict s, const char *restrict format, …);
int snprintf(char *str, size_t size, const char *format, …);
int fprintf(FILE *stream, const char *format, …);

  • char *fgets(char *restrict s, int n, FILE *restrict stream);
    #include <stdio.h>

description:
The functionality described on this reference page is aligned with
the ISO C standard. Any conflict between the requirements described
here and the ISO C standard is unintentional. This volume of
POSIX.1‐2008 defers to the ISO C standard.
The fgets() function shall read bytes from stream into the array
pointed to by s, until n−1 bytes are read, or a is read and
transferred to s, or an end-of-file condition is encountered. The
string is then terminated with a null byte.
The fgets() function may mark the last data access timestamp of the
file associated with stream for update. The last data access
timestamp shall be marked for update by the first successful
execution of fgetc(), fgets(), fread(), fscanf(), getc(), getchar(),
getdelim(), getline(), gets(), or scanf() using stream that returns
data not supplied by a prior call to ungetc().
return value:
Upon successful completion, fgets() shall return s. If the stream is
at end-of-file, the end-of-file indicator for the stream shall be set
and fgets() shall return a null pointer. If a read error occurs, the
error indicator for the stream shall be set, fgets() shall return a
null pointer, and shall set errno to indicate the error.

  • int sprintf(char *restrict s, const char *restrict format, …);
    #include <stdio.h>

description:
sprintf(), snprintf(), vsprintf() and vsnprintf() write to the character string str.
return value:
Upon successful return, these functions return the number of characters printed
(excluding the null byte used to end output to strings).

  • int snprintf(char *str, size_t size, const char *format, …);
    #include <stdio.h>

description:
The functions snprintf() and vsnprintf() write at most size bytes (including the
terminating null byte (’\0’)) to str.
the functions printf(), fprintf(), sprintf(), snprintf(), respectively, except
that they are called with a va_list instead of a variable number of arguments.
These functions do not call the va_end macro. Because they invoke the va_arg
macro, the value of ap is undefined after the call.
return value:
The functions snprintf() and vsnprintf() do not write more than size bytes
(including the terminating null byte (’\0’)). If the output was truncated due to
this limit then the return value is the number of characters (excluding the ter‐
minating null byte) which would have been written to the final string if enough
space had been available. Thus, a return value of size or more means that the
output was truncated. (See also below under NOTES.)

  • int fprintf(FILE *stream, const char *format, …);
    #include <stdio.h>

description:
fprintf() and vfprintf() write output to the given
output stream;
the functions fprintf() respectively, except
that they are called with a va_list instead of a variable number of arguments.
These functions do not call the va_end macro. Because they invoke the va_arg
macro, the value of ap is undefined after the call.
return value:
Upon successful return, these functions return the number of characters printed
(excluding the null byte used to end output to strings).

系统调用接口

#include <fcntl.h>

  • open不定参函数(C语言中没有函数重载)

必选:
O_RDONLY / O_WRONLY / O_RDWR
可选:
O_CREAT: 文件存在打开,不存在创建
O_EXCL: 文件不存在则创建,存在就报错返回
O_TRUNC:打开的同时清空内容
O_APPEND:追加写入
返回值: 正整数–文件描述符–后期对文件操作的操作句柄
失败返回-1

库函数封装系统调用时:
r+: O_RDWR
w+: O_RDWR | O_TRUNC | O_CREAT
a+: O_RDWR | O_APPEND | O_CREAT

  • ssize_t write(int fd, char* data, size_t count )

fd:文件描述符(open函数返回的句柄)
data:写入的数据首地址
count:写入的数据长度
返回值:成功返回写入的字节数,失败-1,

  • ssize_t read(int fd, char* buf, size_t count)

fd: 文件描述符(open函数返回的句柄)
buf: 一块缓冲区的首地址,用于存储读取的数据
count:想要读取的数据长度
0 实际读取的数据长度, -1错误, 0读到了文件末尾

  • off_t fseek(int fd,long offset,int whence)
    fseek返回值是跳转后的位置相对于文件起始位置的偏移量

  • close(int fd);

stid suid
注意事项:

1、如果open使用O_CREAT,那么就一定要加上第三个权限参数
2、权限参数-0664,不要忘了前边这个0;

文件描述符
  • 文件描述符,是一个文件描述信息结构体数组的下标
    srtuct files_struct(struct file* fd_arry[])
    struct file
    进程通过pcb找到files_struct,进而找到fd_arry, 再通过描述符找到具体的文件描述信息元素

FILE结构体中有一个 unsigned int f_flags 成员,对应系统调用open的int flags参数

一个程序运行起来会默认打开三个文件
标准输入,标准输出和标准错误
stdin stdout stderror他们都是FILE*类型的

  • 重定向原理
    通过改变文件描述符这个下标对应的文件描述信息结构,来改变所操作的文件

dup2(int oldfd, int newfd)

  • 文件描述符与文件流指针的关系
    文件描述符:系统调用的操作句柄(系统调用)
    文件流指针:库函数的操作句柄(库函数)
    文件流指针是一个结构体,内部封装了文件描述符

在minishell中如何实现重定向
‘>>’ 追加
‘>’ 清空

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/wait.h>

int main()
{
    while(1) {
        printf("[username@localhost ]$ ");
        fflush(stdout);//手动刷新缓冲区
        char buf[1024] = {0};
        fgets(buf, 1024, stdin);//从标准输入读取数据
        //将最后的换行符修改为字符串结尾标志
        buf[strlen(buf) - 1] = '\0';
        printf("cmd:[%s]\n", buf);


        //[   ls     -a    -l    ]
        char *ptr = buf;
        char *argv[32] = {NULL};
        int argc = 0;
        while(*ptr != '\0') {
            if (!isspace(*ptr)) {
                //每一个非空白字符处,都是参数的起始位置
                argv[argc++] = ptr;
                while(*ptr != '\0' && !isspace(*ptr)) ptr++;
                *ptr = '\0';
            }
            ptr++;
        }
        argv[argc] = NULL;//最后一个参数以NULL结尾
        for (int i = 0; i < argc; i++) {
            printf("argv[%d]=[%s]\n", i, argv[i]);
        }

        //不是直接对shell进行程序替换,因为替换后就没有shell
        pid_t pid = fork();
        if (pid == 0) {
            execvp(argv[0], argv);//子进程进行程序替换
            exit(0);
        }
        waitpid(pid, NULL, 0);//阻塞等待子进程命令执行完毕
    }
    return 0;
}


文件系统(ext2)
  • ext2文件系统将磁盘分成多个分区

超级块
inode_bitmap
data_bitmap
inode
data

  • 文件存储流程:

通过超级快找到各个区域的起始地址,通过inode_bitmap快速找到空闲的inode节点,通过data_bitmap找到空闲数据块,空闲数据块存储文件数据,inode节点存放文件的源信息以及数据存储的块号,组织一个目录项信息,写入到所在目录的文件中

  • 文件读取:

通过文件路径名,到所在目录文件中查找目录项,获取到文件的Inode结点号,在inode区域找到指定的Inode结点,获取到文件的元信息以及数据块号,进而从指定的数据块获取问价数据

符号链接文件
创建软链接文件
ln -s file_name1 file_name2.soft
创建硬链接文件
ln file_name1 file_name2.hard
软链接文件: 是一个独立的文件,有自己的inode节点,文件数据中保存的是源文件路径
硬链接文件:只是文件的一个别名(目录项),与源文件没什么区别,都是文件的目录项,共用同一个inode节点

动态库与静态库的打包与使用
  • 生成:将大量代码进行打包

动态库:
1、gcc -c child.c -o child.o
2、gcc -shared(–share) child.o -o libmychild.so
-fPIC:产生与位置无关代码
-c:只进行预处理,编译,汇编,但是不链接
-shared:生成的是动态库而不是可执行程序
动态库的命名方式:以lib为前缀,以.so为后置,中间是名称

静态库:
1、gcc -c child.c -o child.o
2、 ar -rc libmychild.a child.o
ar 生成静态库的命令
-c:创建
-r:模块替换
命名方式:以lib为前缀,以.a为后置,中间是名称

  • 使用:

生成可执行程序的时候链接使用:
gcc main.c -o main -lmychild
1、将库文件放到指定的路径下:/lib64 /usr/lib64  
2、设置环境变量:
export LIBRARY_PATH=${LIBRARY_PATH}:./ 
3、设置gcc选项: gcc main.c -o main –L./lib -lmychild 
gcc _L选项,用于指定库的链接搜索路径  

运行可执行程序的时候加载使用:仅针对动态链接生成的可执行程序
1、将库文件放到指定的路径下:
/lib64 /usr/lib64
2、设置环境变量:
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:./lib

使用第三方库,这个库通常只有你一个程序使用,因此更多的会使用静态库

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_43808700/article/details/115855164

智能推荐

c# 调用c++ lib静态库_c#调用lib-程序员宅基地

文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib

deepin/ubuntu安装苹方字体-程序员宅基地

文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang

html表单常见操作汇总_html表单的处理程序有那些-程序员宅基地

文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些

PHP设置谷歌验证器(Google Authenticator)实现操作二步验证_php otp 验证器-程序员宅基地

文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器

【Python】matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距-程序员宅基地

文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距

docker — 容器存储_docker 保存容器-程序员宅基地

文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器

随便推点

网络拓扑结构_网络拓扑csdn-程序员宅基地

文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn

JS重写Date函数,兼容IOS系统_date.prototype 将所有 ios-程序员宅基地

文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios

如何将EXCEL表导入plsql数据库中-程序员宅基地

文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql

Git常用命令速查手册-程序员宅基地

文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...

分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120-程序员宅基地

文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120

【C++缺省函数】 空类默认产生的6个类成员函数_空类默认产生哪些类成员函数-程序员宅基地

文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数

推荐文章

热门文章

相关标签