一、目录相关函数及属性
1、 opendir()函数
opendir 用于打开一个目录,并返回一个目录流指针。name:要打开的目录的路径。
返回值:成功时返回指向目录流的指针,失败时返回 NULL。
#include <dirent.h>
DIR *opendir(const char *name);
2、readdir()函数
readdir用于读取目录中的一个条目(如文件或子目录)。每次调用会返回下一个目录条目,直到所有条目都读取完毕.
dirp:通过opendir打开的目录流指针。
返回值:成功时返回指向目录条目的指针,失败时返回 NULL。
#include <dirent.h>
struct dirent *readdir(DIR *dirp);
struct dirent结构通常包含以下成员:d_name:文件或目录的名称。d_ino:文件的索引节点号(inode number)。
3、closedir()函数
closedir用于关闭一个已打开的目录流。 参数:opendir的返回结果中目录流对象。返回值:成功时返回 0,失败时返回 -1
#include <dirent.h>
int closedir(DIR *dirp);
4、chdir函数
chdir用于更改当前工作目录。参数: path:改变到的路径。返回值:成功返回0、失败返回-1。
#include <unistd.h>
int chdir(const char *path);
5、getcwd函数=>pwd
getcwd用于获取当前工作目录的绝对路径参数: buf:保存工作路径空间的首地址、 size:保存路径空间的长度
返回值: 成功返回包含路径空间的字符串首地址、失败返回NULL。
#include <unistd.h>
char *getcwd(char *buf, size_t size);
6、mkdir函数=>mkdir
mkdir()用于创建一个新的目录、LInux中区分大小写的。
pathname:要创建的目录的路径。
mode:目录的权限设置(如 0755 表示所有者可以读写执行,组和其他用户只读执行)。
返回值:成功时返回 0,失败时返回 -1。
#include <sys/stat.h>
#include <sys/types.h>
int mkdir(const char *pathname, mode_t mode);
7、rmdir函数=>rm
rmdir()删除一个空目录文件
pathname:要删除的目录的路径。该目录必须是空的,否则删除会失败。
返回值:成功时返回 0,失败时返回 -1
#include <unistd.h>
int rmdir(const char *pathname);
8、remove函数=>mv
remove用于删除指定的文件或空目录。
pathname:要删除的文件或空目录的路径。
返回值:成功时返回 0,失败时返回 -1。
说明:
如果路径指向的是一个文件,remove 将删除该文件。
如果路径指向的是一个目录,则该目录必须为空,否则删除将失败。
删除非空目录:remove不能删除非空目录,如果需要删除非空目录,应使用系统特定的函数或递归删除目录下的所有内容。
#include <stdio.h>
int remove(const char *pathname);
9、rename函数=>mv
rename用于重命名文件或目录,或者将文件或目录移动到新的位置。
oldpath:原文件或目录的路径。
newpath:新文件或目录的路径(可以是新的名字或新的路径)。
返回值:成功时返回 0,失败时返回 -1。
说明:
如果newpath已经存在,并且newpath 是一个文件,那么它将被删除并替换为oldpath。
如果newpath是一个目录,且目录非空,那么重命名操作将失败。
rename既可以重命名文件,也可以重命名目录,甚至可以跨目录移动文件或目录。
跨文件系统重命名:在某些文件系统上,rename可能不支持跨文件系统重命名或移动文件,在这种情况下,通常需要手动复制并删除文件
#include <stdio.h>
int rename(const char *oldpath, const char *newpath);
10、stat()函数=>stat
stat是一个在类 Unix 操作系统中非常有用的系统调用,用于获取文件或目录的详细信息,包括文件的大小、权限、修改时间等。使用stat可以获取一个文件或目录的状态信息。
pathname:文件或目录的路径。
statbuf:指向 struct stat结构体的指针,用于存储获取的文件或目录的状态信息。
返回值:成功时返回 0,失败时返回 -1。
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *pathname, struct stat *statbuf);
stat函数通过struct stat 结构返回文件的状态信息。该结构体定义如下 :
struct stat {
dev_t st_dev; // 文件所在的设备
ino_t st_ino; // 文件的节点号
mode_t st_mode; // 文件的类型和权限
nlink_t st_nlink; // 硬链接的数量
uid_t st_uid; // 所有者的用户ID
gid_t st_gid; // 所有者的组ID
dev_t st_rdev; // 若此文件为设备文件,则为其设备号
off_t st_size; // 文件大小,以字节为单位
blksize_t st_blksize; // 文件系统的块大小
blkcnt_t st_blocks; // 文件所占的块数
time_t st_atime; // 最后一次访问时间
time_t st_mtime; // 最后一次修改时间
time_t st_ctime; // 最后一次状态变化时间
};
常用的 st_mode 值:
S_IFREG:普通文件
S_IFDIR:目录
S_IFLNK:符号链接
S_IFCHR:字符设备
S_IFBLK:块设备
S_IFIFO:FIFO (管道)
S_IFSOCK:套接字
此外,st_mode中还包含了文件权限位,如:
S_IRUSR:所有者可读
S_IWUSR:所有者可写
S_IXUSR:所有者可执行
11、truncate函数
truncate是一个系统调用,用于调整文件的大小。如果新大小小于文件当前大小,则文件会被截断;如果新大小大于文件当前大小,则文件会被扩展,并用空字节(通常为零)填充扩展部分。
path:文件的路径。
length:文件的新大小。
返回值:成功时返回 0,失败时返回 -1
二、软链接与硬链接
软链接(符号链接)是一个指向另一个文件或目录的特殊文件。它类似于 Windows 中的快捷方式。//ln -s 123 softlink 快捷方式
特点:
- 软链接只是一个指向目标文件的路径,并不包含目标文件的内容。
- 软链接可以跨文件系统创建。
- 如果目标文件被删除,软链接会变为“断开的链接”,因为它指向一个不存在的文件。
target:目标文件或目录的路径名。
linkpath:符号链接的路径名(即将要创建的符号链接的名称)。
返回值:成功时返回 0,失败时返回 -1
#include <unistd.h>
int symlink(const char *target, const char *linkpath);
硬链接是文件系统中指向同一文件数据的多个文件名。硬链接与目标文件共享相同的 inode 号码,因此它们实际上是同一个文件,只是有不同的文件名。//link ln 1 2
特点:
- 硬链接指向相同的文件数据,删除一个硬链接不会影响其他硬链接。
- 硬链接不能跨文件系统创建。
- 硬链接不能链接到目录(除非使用特定的系统选项或特殊的文件系统)
参数: oldpath:现有文件的路径名。
newpath:硬链接的路径名(即将要创建的硬链接的名称)。
返回值:成功时返回 0,失败时返回 -1。
#include <unistd.h>
int link(const char *oldpath, const char *newpath);
三、报错函数
在 C 语言中,perror()、strerror()和 error()是处理和显示错误信息的常用函数或宏。它们主要用于调试和错误处理,让程序员可以理解程序运行时的错误原因。
1.perror() 函数 void perror(const char *s);
perror()是一个标准库函数(stdio.h库),用于输出上一个库函数调用失败的原因。它会根据全局变量 errno的值来输出相应的错误信息。
s:这是一个字符串,通常是描述发生错误的上下文。perror()会先输出这个字符串,然后在后面加上一个冒号和空格,再输出根据 `errno` 解释的错误信息。无返回值
#include <stdio.h>
int main() {
FILE *fp = fopen("non_existent_file.txt", "r");
if (fp == NULL) {
perror("Failed to open file");
return -1;
}
return 0;
}
//输出Failed to open file: No such file or directory
2.strerror()函数 char *strerror(int errnum);
strerror()是一个标准库函数(string.h库),用于将错误号(通常是 errno)转换为描述错误的字符串。它返回一个指向错误消息字符串的指针。
errnum:这是一个错误号(通常是 errno的值)。
返回值:返回指向错误消息字符串的指针
#include <stdio.h>
#include <string.h>
#include <errno.h>//错误号变量
int main() {
int errnum = ENOENT; // "No such file or directory" error code
printf("Error message: %s\n", strerror(errnum));
//输出Error message: No such file or directory
return 0;
}
3.error()函数
error()不是标准的 C 库函数,但在 GNU C 库 (glibc) 中可用。它用于打印错误消息,并可选地终止程序。error() 函数还允许指定一个自定义的退出状态码。
status:如果 status不为 0,error()会调用 exit(status)以终止程序;如果为 0,程序将继续执行。
errnum:通常是 errno,表示错误号。如果 errnum为 0,不会输出任何错误消息,只输出 format指定的自定义信息。
format:这是一个格式化字符串,类似于 printf,用于输出自定义错误消息。
返回值:无返回值
#include <stdio.h>
#include <error.h>
#include <errno.h> //extern int errno
int main(int argc, char *argv[])
{
FILE* fp = fopen("aaa","r");
if(NULL == fp)
{
//perror("fopen");
error(1,errno,"fopen,file:%s fun:%s line:%d",__FILE__,__func__,__LINE__);
printf("aaaa\n");
return -1;
}
return 0;
}
总结:
perror():输出自定义字符串和标准错误消息,适用于快速输出错误信息。
strerror():将错误码转换为可读的错误字符串,适用于需要将错误信息作为字符串处理的场合。
error()(GNU扩展):输出格式化的错误消息,并可选择是否退出程序,提供了更灵活的错误处理方式。
__FILE__: 表示是那个文件
__LINE__:表示第几行
__func__:表示在那个函数
__DATE__:编译时表示日期
__TIME__:编译时表示时间
四、获取用户和组相关函数
1.组函数
struct group {
char *gr_name; // 组名
char *gr_passwd; // 组密码
gid_t gr_gid; // 组ID
char **gr_mem; // 组成员列表
};
1.getgrgid()函数
getgrgid()函数用于根据组ID (GID) 查找组信息,并返回指向 struct group结构体的指针。
返回值:指向 struct group结构体的指针,包含了组的名称、组ID、组成员等信息。如果没有找到对应的组,返回 NULL。
#include <stdio.h>
#include <grp.h>
int main() {
gid_t gid = 1000; // 例如,组ID为1000
//struct group *getgrgid(gid_t gid);
struct group *grp = getgrgid(gid);
if (grp != NULL) {
printf("Group name: %s\n", grp->gr_name);
} else {
perror("Group not found");
}
return 0;
}
2.getgrnam()函数
getgrnam()函数用于根据组名查找组信息,并返回指向 struct group结构体的指针。
返回值:指向 struct group 结构体的指针。如果没有找到对应的组,返回 NULL
#include <stdio.h>
#include <grp.h>
//struct group *getgrnam(const char *name);
int main() {
const char *group_name = "staff"; // 例如,组名为"staff"
struct group *grp = getgrnam(group_name);
if (grp != NULL) {
printf("Group ID: %d\n", grp->gr_gid);
} else {
perror("Group not found");
}
return 0;
}
2.用户函数
struct passwd {
char *pw_name; // 用户名
char *pw_passwd; // 用户密码
uid_t pw_uid; // 用户ID
gid_t pw_gid; // 组ID
char *pw_gecos; // 用户全名
char *pw_dir; // 用户的主目录
char *pw_shell; // 用户的登录 shell
};
getpwuid()函数
getpwuid()函数用于根据用户ID (UID) 查找用户信息,并返回指向 struct passwd结构体的指针。
#include <stdio.h>
#include <pwd.h>
int main() {
uid_t uid = 1000; // 例如,用户ID为1000
struct passwd *pw = getpwuid(uid);
if (pw != NULL) {
printf("User name: %s\n", pw->pw_name);
} else {
perror("User not found");
}
return 0;
}
getpwnam()函数
getpwnam()函数用于根据用户名查找用户信息,并返回指向 struct passwd结构体的指针。
#include <stdio.h>
#include <pwd.h>
int main() {
const char *user_name = "john"; // 例如,用户名为"john"
struct passwd *pw = getpwnam(user_name);
if (pw != NULL) {
printf("User ID: %d\n", pw->pw_uid);
} else {
perror("User not found");
}
return 0;
}
五、时间函数
C 语言中的时间相关函数主要包含在 `<time.h>` 头文件中。这些函数用于处理和操作日期和时间,支持获取当前时间、格式化时间、测量时间间隔等操作。
struct tm {
int tm_sec; // 秒,范围为 0-60,允许闰秒(考虑到可能存在的闰秒,所以有可能为 60)
int tm_min; // 分,范围为 0-59
int tm_hour; // 时,范围为 0-23
int tm_mday; // 一个月中的某一天,范围为 1-31
int tm_mon; // 月,范围为 0-11(0 表示 1 月,1 表示 2 月,以此类推)
int tm_year; // 年份,自 1900 年起算,即 2024 年表示为 2024-1900 = 124
int tm_wday; // 一周中的某一天,范围为 0-6(0 表示星期天,1 表示星期一,以此类推)
int tm_yday; // 一年中的某一天,范围为 0-365(0 表示 1 月 1 日)
int tm_isdst; // 夏令时标志,正值表示夏令时生效,零表示夏令时不生效,负值表示不确定
};
以下是一些常用的时间相关函数:
1. time()函数
time()函数用于获取当前的日历时间,并返回Epoch时间(1970-01-01 00:00:00 UTC)以来经过的秒数。
t:如果t不是NULL,则time_t值也会存储在t指向的内存中。
返回值:返回当前时间的time_t值(通常是一个长整型整数),如果失败返回(time_t)-1。
#include <time.h>
time_t time(time_t *t);
2. ctime()函数
ctime()函数将时间值(time_t类型)转换为字符串形式的本地时间,格式为 "Www Mmm dd hh:mm:ss yyyy\n"。
t:指向要转换的time_t时间值的指针。
返回值:返回指向字符串的指针,包含格式化的本地时间字符串。如果失败,返回 NULL。
#include <stdio.h>
#include <time.h>
int main() {
time_t current_time = time(NULL);
printf("Current time: %s", ctime(¤t_time));
//Current time: Tue Aug 15 14:30:00 2024
return 0;
}
3. difftime()函数
difftime()函数用于计算两个时间值之间的差值,并以秒为单位返回结果。
end:结束时间的time_t值。
start:开始时间的time_t值。
返回值:返回end和start之间的时间差(以秒为单位)。
#include <stdio.h>
#include <time.h>
int main() {
time_t start_time = time(NULL);
// 模拟某种延迟
sleep(2);
time_t end_time = time(NULL);
double elapsed = difftime(end_time, start_time);
printf("Elapsed time: %.2f seconds\n", elapsed);
return 0;
}
4. localtime()函数
localtime()函数将time_t类型的时间值转换为当地时间,并返回指向struct tm结构体的指针。
timep:指向要转换的time_t时间值的指针。
返回值:返回指向 struct tm的指针,包含分解的本地时间信息。如果失败,返回 NULL。
#include <stdio.h>
#include <time.h>
int main() {
time_t current_time = time(NULL);
struct tm *local_time = localtime(¤t_time);
printf("Local time: %02d:%02d:%02d\n",
local_time->tm_hour, local_time->tm_min, local_time->tm_sec);
return 0;
}
5. mktime()函数
mktime()函数将struct tm结构体表示的时间转换为time_t类型的日历时间(秒数)。
timeptr:指向要转换的 struct tm结构体的指针。
返回值:返回 time_t值(自 Epoch 时间以来的秒数),如果失败返回 (time_t)-1。
#include <stdio.h>
#include <time.h>
int main() {
struct tm time_info = {0};
time_info.tm_year = 2024 - 1900; // 年份从1900年开始
time_info.tm_mon = 7; // 8月,从0开始
time_info.tm_mday = 15;
time_info.tm_hour = 14;
time_info.tm_min = 30;
time_info.tm_sec = 0;
time_t t = mktime(&time_info);
printf("Time in seconds since Epoch: %ld\n", t);
return 0;
}
6. strftime()函数
strftime()函数根据格式字符串生成格式化的时间字符串。
s:存放结果的字符串缓冲区。
max:缓冲区的最大长度。
format:格式字符串,类似于printf的格式字符串。
tm:指向struct tm结构体的指针,包含时间信息。
返回值:返回写入缓冲区的字符数。
#include <stdio.h>
#include <time.h>
int main() {
time_t current_time = time(NULL);
struct tm *local_time = localtime(¤t_time);
char buffer[80];
strftime(buffer, sizeof(buffer), "Date: %Y-%m-%d Time: %H:%M:%S", local_time);
printf("%s\n", buffer);
return 0;
}
总结:
time():获取当前时间,以秒为单位。
ctime():将time_t时间转换为字符串形式的本地时间。
difftime():计算两个time_t时间之间的差值。
localtime():将time_t时间转换为本地时间的struct tm结构体。
gmtime():将time_t时间转换为 UTC 时间的struct tm结构体。
mktime():将 struct tm结构体转换为time_t时间。
strftime():根据格式字符串生成格式化的时间字符串。
这些函数提供了丰富的时间处理功能,适用于不同的时间和日期操作场景。