file*p 和int fd转换的函数
fileno( FILE *p ->int fd)
函数原型
int fileno(FILE *stream);
参数说明
-
stream
: 指向FILE
结构的指针,表示要获取文件描述符的流。
返回值
-
成功时,返回与
stream
相关联的文件描述符。 -
如果
stream
是NULL
或者其他错误发生,返回-1
。
使用案例
#include <stdio.h>
#include <unistd.h>int main() {FILE *fp = fopen("example.txt", "w");if (fp == NULL) {perror("Error opening file");return 1;}// 获取文件流的文件描述符int fd = fileno(fp);printf("The file descriptor is: %d\n", fd);// 使用文件描述符进行操作,例如关闭文件close(fd); // 注意:这将关闭与流关联的底层文件描述符return 0;
}
fdopen
函数原型
FILE *fdopen(int fd, const char *mode);
参数说明
-
fd
: 一个整数,表示已打开的文件描述符。 -
mode
: 一个字符串,指定了流的模式,可以是 "r"、"w"、"a" 等,类似于fopen
函数中的模式参数。
返回值
-
成功时,返回指向新创建的
FILE
流对象的指针。 -
失败时,返回
NULL
并设置errno
以指示错误。
示例
#include <stdio.h>
#include <fcntl.h>int main() {int fd = open("example.txt", O_RDONLY);if (fd == -1) {perror("open");return 1;}FILE *fp = fdopen(fd, "r"); // 将文件描述符与读模式的流关联if (fp == NULL) {perror("fdopen");close(fd);return 1;}// 使用标准I/O函数操作文件...fclose(fp); // 关闭流,注意这不会关闭底层的文件描述符close(fd); // 需要手动关闭文件描述符return 0;
}
需要注意的是,fclose
不会关闭底层的文件描述符,因此需要手动关闭它 。
目录
目录可以当作文件来看,只不过读取目录操作不一样。
1.打开目标目录
2.读取目录
3.关闭目录
目录操作的函数
1.opendir
原型
DIR *opendir(const char *dirname);
参数说明
-
dirname
: 一个指向以 null 结尾的字符串的指针,表示要打开的目录的路径。 -
DIR* 目录流指针
返回值
-
成功时,返回指向
DIR
结构的指针,该结构用于后续的目录读取操作。 -
失败时,返回
NULL
并设置errno
以指示错误类型。
错误处理
如果 opendir
调用失败,errno
可能会被设置为以下值之一:
-
EACCES
: 权限不足,无法访问指定的目录。 -
EMFILE
: 进程已经达到了文件描述符的限制。 -
ENFILE
: 系统已经达到了文件描述符的限制。 -
ENOENT
: 指定的目录不存在。 -
ENOTDIR
:dirname
不是一个目录。 -
EBADF
: 无效的目录流。
readdir
原型
struct dirent *readdir(DIR *dir);
参数说明
-
dir
: 指向之前使用opendir
成功打开的目录流的指针。
返回值
-
成功时,返回指向
struct dirent
的指针,该结构包含了目录条目的信息。 -
到达目录流末尾或发生错误时,返回
NULL
。
结构体 struct dirent
struct dirent
通常包含以下字段:
-
d_ino
: 条目的 inode 号(在某些系统上可能不可用)。 -
d_off
: 目录流中的偏移量,可以用于seekdir
或telldir
。 -
d_reclen
:struct dirent
条目的长度。 -
d_type :文件类型
-
d_name
: 以 null 结尾的字符数组,包含了条目的名称。//char型
closedir
原型:
int closedir(DIR *dir);
参数说明
-
dir
: 指向之前使用opendir
成功打开的目录流的指针。
返回值
-
成功关闭目录流时,返回 0。
-
如果发生错误,返回
-1
并设置errno
以指示错误类型。
应用:打开当前目录
int main(int argc, const char *argv[])
{DIR * dir=opendir("./");//当前目录if(NULL==dir){fprintf(stderr,"opendir error\n");return 1;}while(1){struct dirent *info =readdir(dir);if(NULL== info){break;}printf("%s\n",info->d_name);}closedir(dir);return 0;
}
结果
1.txt
. //表示当前文件
a.out
lesson.c
.. //表示上一路径
需要注意, . ,.. 着两个目录是所有目录都有的,一个表示当前的目录,一个表示上一路径。
根目录相关函数
chdir (cd)
原型
int chdir(const char *path);
参数说明
-
path
: 一个指向以 null 结尾的字符串的指针,表示要切换到的目标目录的路径。
返回值
-
成功时,返回 0。
-
失败时,返回 -1 并设置
errno
以指示错误类型。
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{int ret = chdir("..");if(-1 == ret){fprintf(stderr,"chdir error\n");return 1;}fopen("aaa","w");return 0;
}
getcwd (pwd)
原型
char *getcwd(char *buf, size_t size);
参数说明
-
buf
: 一个指向字符数组的指针,用于接收当前工作目录的路径。如果为NULL
,则函数会分配一个足够大的缓冲区。 -
size
:buf
数组的大小(以字节为单位)。如果buf
为NULL
,这个参数会被忽略。
返回值
-
成功时,返回指向包含当前工作目录路径的字符串的指针。
-
失败时,返回
NULL
并设置errno
以指示错误类型。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[])
{char buf[256]={0};getcwd(buf,sizeof(buf));printf("current path is %s\n",buf);chdir("../");getcwd(buf,sizeof(buf));printf("change path is %s\n",buf);return 0;
}
练习:寻找目录下的.c文件
int main(int argc, const char *argv[])
{char buf[512]={0}; if(argc<2){fprintf(stdout," usage error\n");return 1;}DIR * dir=opendir(argv[1]);if(NULL==dir){fprintf(stderr,"opendir error\n");return 1;}while(1){struct dirent *info =readdir(dir);if(NULL== info){break;}int k=strlen(info->d_name);if(k>=3){if((info->d_name)[k-1]=='c'&&(info->d_name)[k-2]=='.'){printf("%s\n",info->d_name);}}}closedir(dir);return 0;}
mkdir
原型
int mkdir(const char *path, mode_t mode);
参数说明
-
path
: 一个指向以 null 结尾的字符串的指针,表示要创建的目录的路径。 -
mode
: 新创建目录的权限模式。这个模式受进程的 umask 影响,并且可以包括文件访问权限位,例如S_IRWXU
(可读、可写、可执行)等。
返回值
-
成功时,返回 0。
-
失败时,返回 -1 并设置
errno
以指示错误类型。
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
int main(int argc, char *argv[])
{int ret = mkdir("aaa",0777);if(-1 == ret){fprintf(stderr,"mkdir error\n");return 1;}return 0;
}
rmdir
原型
int rmdir(const char *path);
参数说明
-
path
: 一个指向以 null 结尾的字符串的指针,表示要删除的目录的路径。
返回值
-
成功时,返回 0。
-
失败时,返回 -1 并设置
errno
以指示错误类型。
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{int ret = rmdir("./aaa");if(-1 == ret){fprintf(stderr,"rmdir error\n");return 1;}return 0;
}
注意,这个函数只能删除空目录,即目录下无文件,该函数用的比较少,一般用rm。
文件相关函数
stat
用于获取文件或目录的状态信息。
原型
int stat(const char *path, struct stat *buf);
参数说明
-
path
: 一个指向以 null 结尾的字符串的指针,表示要获取状态信息的文件或目录的路径。 -
buf
: 一个指向struct stat
结构的指针,该结构用于接收文件或目录的状态信息。
返回值
-
成功时,返回 0。
-
失败时,返回 -1 并设置
errno
以指示错误类型。
结构体 struct stat
struct stat
结构包含了以下一些字段(具体字段可能因系统而异):
-
st_dev
: 设备 ID,文件所在的设备。 -
st_ino
: inode 号,唯一标识文件系统中的文件。 -
st_mode
: 文件模式,包含文件类型和权限。 -
st_nlink
: 硬链接数。 -
st_uid
和st_gid
: 文件所有者的用户 ID 和组 ID。 -
st_size
: 文件大小,以字节为单位。 -
st_blksize
: 块大小,最优 I/O 操作块大小。 -
st_blocks
: 占用的块数。 -
st_atime
,st_mtime
,st_ctime
: 访问时间、修改时间和状态改变时间。
系统时间获取
1.time
在 C 语言中,time
是一个与时间和日期相关的函数,它用于获取当前时间自纪元(Epoch,即1970年1月1日 00:00:00 UTC)以来的秒数。这个函数定义在 <time.h>
头文件中。
原型
time_t time(time_t *tp);
参数说明
-
tp
: 一个指向time_t
类型的可选参数。如果提供了这个参数,time
函数会将当前时间的副本存储在tp
指向的位置。
返回值
-
成功时,返回当前时间自纪元以来的秒数。
-
失败时,返回
((time_t) -1)
并设置errno
以指示错误类型。
时间转换函数
1.ctime()
原型
char *ctime(const time_t *timep);
参数说明
-
timep
: 指向time_t
类型的指针,表示要转换的时间戳。
返回值
-
ctime
返回一个以 null 结尾的字符串,该字符串表示对应的时间戳。格式通常是 "Wed Jun 21 23:59:59 1999\n"。 -
注意:返回的字符串存储在静态内存中,因此每次调用
ctime
都会覆盖上一次的返回值。
#include <stdio.h>
#include <time.h>int main() {time_t current_time = time(NULL); // 获取当前时间的时间戳if (current_time == ((time_t) -1)) {perror("time failed");return 1;}// 将时间戳转换为可读的字符串char *time_str = ctime(¤t_time);printf("Current time: %s", time_str);return 0;
}
2.localtime
原型
struct tm *localtime(const time_t *timep);
参数说明
-
timep
: 指向time_t
类型的指针,表示要转换的时间戳。
返回值
-
localtime
返回一个指向struct tm
的指针,该结构包含了本地时间的详细信息。 -
如果转换失败,返回
NULL
并设置errno
。
结构体 struct tm
struct tm
结构包含了以下字段:
-
tm_sec
: 秒(0-59)。 -
tm_min
: 分钟(0-59)。 -
tm_hour
: 小时(0-23)。 -
tm_mday
: 一个月中的第几天(1-31)。 -
tm_mon
: 年份中第几个月,从0
(1月)开始。 -
tm_year
: 自 1900 年以来的年数。 -
tm_wday
: 一周中的第几天,从0
(周日)开始。 -
tm_yday
: 一年中的第几天,从0
(1月1日)开始。 -
tm_isdst
: 夏令时标志。