文件操作相关函数
一、symlink 函数
int symlink(const char *oldpath, const char *newpath);
功能:
创建一个指向 oldpath 文件的新的符号链接(软链接)文件。
参数:
• oldpath:被链接指向的原始文件的路径。
• newpath:新创建的符号链接文件的路径。
返回值:
• 成功时,返回 0 。
• 失败时,返回 -1 。
#include <stdio.h>
#include <unistd.h>
int main(int argc, const char *argv[])
{
// 以只写方式打开文件"aaa"
fopen("aaa","w");
// 创建一个指向文件"aaa"的符号链接"bbb",并将返回值存储在 link 中
int link = symlink("./aaa","bbb");
// 如果创建符号链接失败(返回值为 -1)
if( link == -1 )
{
// 向标准错误输出"symlink error"
fprintf(stderr,"symlink error\n");
// 程序返回 1,表示出现错误
return 1;
}
// 程序正常返回 0
return 0;
}
二、remove 函数
int remove(const char *pathname);
功能:
删除一个文件。
参数:
pathname:要删除文件的路径。
返回值:
• 成功时,返回 0 。
• 失败时,返回 -1 。
#include <stdio.h>
int main(int argc, const char *argv[])
{
// 尝试删除文件"./bbb",并将返回值存储在 rm 中
int rm = remove("./bbb");
// 如果删除操作失败(返回值为 -1)
if ( rm == -1 )
{
// 向标准错误输出"remove error"
fprintf(stderr,"remove error\n");
// 程序返回 1,表示出现错误
return 1;
}
// 程序正常返回 0
return 0;
}
三、rename 函数
int rename(const char *oldpath, const char *newpath);
功能:
将一个文件或目录从旧路径重命名为新路径。
参数:
• oldpath:旧路径。
• newpath:新路径。
返回值:
• 成功时,返回 0 。
• 失败时,返回 -1 。
#include <stdio.h>
int main(int argc, const char *argv[])
{
// 尝试将文件"./aaa"重命名为"bbb",并将返回值存储在 rn 中
int rn = rename("./aaa", "bbb");
// 如果重命名操作失败(返回值为 -1)
if (rn == -1)
{
// 向标准错误输出"rename error"
fprintf(stderr, "rename error\n");
// 程序返回 1,表示出现错误
return 1;
}
// 程序正常返回 0
return 0;
}
四、link 函数
int link(const char *oldpath, const char *newpath);
功能:
创建一个硬链接文件。
参数:
• oldpath:要链接指向的文件。
• newpath:创建的新硬链接文件的路径。
返回值:
• 成功时,返回 0 。
• 失败时,返回 -1 。
#include <stdio.h>
#include <unistd.h>
int main(int argc, const char *argv[])
{
// 尝试创建一个指向文件"./bbb"的硬链接"aaa",并将返回值存储在 lk 中
int lk = link("./bbb", "aaa");
// 如果创建硬链接操作失败(返回值为 -1)
if (lk == -1)
{
// 向标准错误输出"link error"
fprintf(stderr, "link error");
// 程序返回 1,表示出现错误
return 1;
}
// 程序正常返回 0
return 0;
}
五、truncate 函数
int truncate(const char *path, off_t length);
功能:
将指定文件的大小截断为指定的长度。
参数:
• path:要截断的文件的路径。
• length:要截断到的长度。
返回值:
• 成功时,返回 0 。
• 失败时,返回 -1 。
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main(int argc, const char *argv[])
{
// 尝试将文件"./aaa"截断为 1024 * 1024 * 1024 字节大小,并将返回值存储在 tc 中
int tc = truncate("./aaa", 1024 * 1024 * 1024);
// 如果截断操作失败(返回值为 -1)
if (tc == -1)
{
// 向标准错误输出"truncate error"
fprintf(stderr, "truncate error\n");
// 程序返回 1,表示出现错误
return 1;
}
// 程序正常返回 0
return 0;
}
错误处理相关函数
六、perror 函数
void perror(const char *s);
功能:
打印指定的字符串和与当前 errno 值对应的错误信息到标准错误输出。
参数:
s:要在错误信息前打印的字符串。
返回值:
无。
#include <stdio.h>
#include <unistd.h>
int main(int argc, const char *argv[])
{
// 以只读方式打开文件"aaa",并将文件指针存储在 fp 中
FILE * fp = fopen("aaa","r");
// 如果文件打开失败,文件指针为 NULL
if ( fp == NULL )
{
// 向标准错误输出"fopen errro"
fprintf(stderr,"fopen errro\n");
// 调用 perror 函数输出与当前 errno 对应的错误描述
perror("fopen");
// 程序返回 1,表示出现错误
return 1;
}
// 程序正常返回 0
return 0;
}
七、strerror 函数
char *strerror(int errnum);
功能:
根据给定的错误码返回对应的错误信息字符串。
参数:
errnum:错误码。
返回值:
成功时返回对应的错误信息字符串。
#include <stdio.h>
#include <string.h>
int main(int argc, const char *argv[])
{
int i;
// 从 0 到 134 进行循环
for (i = 0; i < 135; i++)
{
// 打印当前的数字 i 以及对应的错误描述字符串
printf("%d: %s\n", i, strerror(i));
}
// 程序正常返回 0
return 0;
}
八、error 函数
void error(int status, int errnum, const char *format,...);
功能:
程序出错时打印对应的出错原因、用户输入的字符串并退出。
参数:
• status:程序退出的状态,如 EXIT_FAILURE(1)或 EXIT_SUCCESS(0)。
• errnum:错误码。
• format:类似 printf 的格式化字符串。
返回值:
无。
C 内置宏
• __FILE__:表示当前源文件的文件名。
• __LINE__:表示当前代码所在的行号。
• __func__:表示当前所在的函数名。
• __DATE__:表示编译日期,格式为 "Mmm dd yyyy"。
• __TIME__:表示编译时间,格式为 "hh:mm:ss"。
#include <stdio.h>
#include <error.h>
#include <unistd.h>
#include <errno.h>
int main(int argc, const char *argv[])
{
// 尝试以只读方式打开文件 "aaa",并将文件指针存储在 fp 中
FILE * fp = fopen("aaa", "r");
// 如果文件打开失败,文件指针为 NULL
if (fp == NULL)
{
// 使用 error 函数打印错误信息并退出程序
// 1 表示退出状态为 1(失败)
// errno 表示获取当前的错误码
// 后面的参数是自定义的错误描述,包含了文件名、行号、函数名、日期和时间等信息
error(1, errno, "fopen,file:%s line:%d func:%s date:%s time:%s\n",
__FILE__, __LINE__, __func__, __DATE__, __TIME__);
return 1;
}
return 0;
}
Makefile 工程管理工具
Makefile 是一种工程管理工具,具有以下特点和作用:
1. 定义规则
◦ 描述了项目中文件之间的依赖关系和生成这些文件的命令。
2. 自动化编译
◦ 当您修改了某些源文件后,Makefile 能够自动确定哪些文件需要重新编译,并执行相应的编译命令,提高开发效率。
3. 灵活配置
◦ 可以方便地设置编译器选项、链接库、包含路径等各种编译和链接参数。
4. 目标管理
◦ 您可以定义不同的目标,例如编译、清理、安装等,通过指定不同的目标来执行不同的操作序列。
5. 跨平台
◦ 其语法相对简单且具有一定的通用性,在不同的操作系统和开发环境中都能使用。
例如,一个简单的 Makefile 可能包含规则,说明如何从源文件生成目标文件,以及如何将目标文件链接成可执行文件。当您运行 make 命令时,它会按照规则进行相应的操作。
比如我要编写三个.c文件,我的Makefile可以这么写:
SRC = main.c # 定义变量 SRC 并初始化为 main.c
SRC += add.c # 向 SRC 变量添加 add.c
SRC += mul.c # 向 SRC 变量继续添加 mul.c
OBJ = all # 定义变量 OBJ 为 all
# 自定义变量
FALG = -g # 定义编译调试标志变量为 -g
LIB = -lm # 定义链接数学库的变量为 -lm
CC = gcc # 定义编译器为 gcc
$(OBJ):$(SRC) # 定义目标 all 依赖于 SRC 变量所包含的源文件
$(CC) $(SRC) -o $(OBJ) $(FALG) $(LIB) # 当 all 目标需要更新时,执行的编译和链接命令
clean: # 定义名为 clean 的目标,用于清理操作
rm $(OBJ) # 执行删除 all 目标文件的操作
这个 Makefile 定义了源文件列表 SRC(包含 main.c、add.c 和 mul.c)和目标文件 OBJ(为 all)。通过自定义变量设置了编译选项 FALG(调试标志)、链接库 LIB(数学库)和编译器 CC(gcc)。
主要目标 all 依赖于源文件,当执行 make all 时,会使用指定的编译器、编译选项和链接库将源文件编译并链接为目标文件 all。
clean 目标用于清理生成的目标文件 all,执行 make clean 时会删除它。
gdb 调试器
gdb (GNU Debugger)是用于调试程序的工具。
• 特点:
◦ 断点设置:可以在代码的特定位置设置断点,使程序在运行到该点时暂停。
◦ 变量查看和修改:能够查看程序运行时变量的值,并在需要时进行修改。
◦ 单步调试:支持逐行执行代码,观察程序的执行流程和状态。
• 用途:
◦ 查找和修复程序中的逻辑错误和运行时错误。
◦ 理解程序的执行过程,优化程序的性能。