需要引用的头文件

#include <unistd.h>

unistd.h 为程序提供了对POSIX操作系统API的访问接口,主要用于提供与系统调用相关的功能。

char *getcwd(char *buf, size_t size);

用于获取当前工作目录(Current Working Directory)的绝对路径。

参数
buf: 指向存放当放当前目录的数组
size: 数组的大小
返回值
成功:返回包含当前工作目录的字符串。如果buf不为NULL,即返回buf。
失败:返回NULL,并设置errno

示例:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>int main() {char *buf = NULL; // 使用动态分配char *cwd = getcwd(buf, 0); // 0 表示动态分配if (cwd == NULL) {perror("getcwd failed");return 1;}printf("Current working directory: %s\n", cwd);free(cwd); // 释放动态分配的内存return 0;
}

运行该程序后,会输出当前工作目录的绝对路径。

如果传入的 buf 为 NULL ,且 size 为 0,则 getcwd 会调用 malloc 申请合适大小的内存空间,填入当前工作目录的绝对路径,然后返回 malloc 申请的空间的地址。
注意: getcwd 不负责 free 申请的空间, free 是调用者的职责。

int chdir(const char *path);

chdir 函数可以改变当前工作目录。
参数
path: 改变后的路径。 

  • 路径可以是绝对路径(从根目录开始),也可以是相对路径(相对于当前工作目录)。

返回值
成功:返回0。
失败:返回-1,并设置errno。

chdir 函数用于将当前进程的工作目录切换到指定的目录。当前工作目录是指当前进程在文件系统中的位置,类似于在命令行中使用 cd 命令的效果。改变工作目录后,所有相对路径的文件操作都将基于新的工作目录进行。

示例:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>int main() {// 尝试切换到指定目录if (chdir("/home/user/project") != 0) {perror("chdir failed");return 1;}printf("Successfully changed directory to /home/user/project\n");// 获取当前工作目录并打印char *buf = NULL; // 使用动态分配char *cwd = getcwd(buf, 0); // 0 表示动态分配if (cwd == NULL) {perror("getcwd failed");return 1;}printf("Current working directory: %s\n", cwd);free(cwd); // 释放动态分配的内存return 0;
}

注意事项

  • 权限问题

    • 调用进程需要有足够的权限才能切换到指定目录。如果目标目录的权限设置不允许当前用户访问,则会返回 EACCES 错误。

  • 线程安全性

    • chdir 函数是线程安全的,可以在多线程程序中安全使用。但是,需要注意的是,改变工作目录会影响整个进程,包括所有线程。

int mkdir(const char *pathname, mode_t mode);

mkdir 函数用于创建一个新的目录。如果指定的路径已经存在,或者路径中某个组件不存在或不是目录,函数将失败并返回相应的错误码。

参数
pathname: 要创建目录的路径
mode: 目录的权限位,会受文件创建掩码umask的影响,实际的权限为(mode & ~umask
& 0777)

umask(用户文件创建掩码,User File Creation Mask)是一个用于控制新创建文件和目录默认权限的机制。它通过限制文件和目录的权限,确保新创建的文件和目录不会被赋予过于宽松的权限。

可以通过在终端中键入 umask 来查看默认掩码值

假设 umask 设置为 0022,那么:

  • 对于文件:

    最终权限=0666&∼0022=0666&0755=0644

    即文件的最终权限为 0644(所有者有读写权限,组内用户和其他用户有读权限)。

返回值
成功:返回0
失败:返回-1,并设置errno

#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>int main() {// 设置 umask 为 0022mode_t old_umask = umask(0022);// 创建目录const char *pathname = "/home/user/newdir";mode_t mode = 0777; // 设置目录权限为 777if (mkdir(pathname, mode) != 0) {perror("mkdir failed");return 1;}printf("Successfully created directory: %s\n", pathname);// 恢复旧的 umaskumask(old_umask);return 0;
}


int rmdir(const char *pathname);

rmdir 函数用于删除一个空目录。如果目录不为空(即目录中包含文件或其他目录),rmdir 将无法删除该目录,并返回 EEXIST 错误。
参数
pathname: 要删除的目录
返回值
成功:返回0
失败:返回-1,并设置errno

#include <func.h>
int main(int argc, char* argv[]) {// ./rmdir dirARGS_CHECK(argc, 2);int ret = rmdir(argv[1]);// 注意:rmdir 只能删除空目录ERROR_CHECK(ret, -1, "rmdir");return 0;
}
  • rmdir 函数用于删除空目录。

  • 如果目录不为空,需要先删除目录中的内容,再删除目录。

如果该目录非空,需要递归删除目录中的内容,实现如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <unistd.h>
#include <sys/stat.h>int remove_directory(const char *pathname) {DIR *dir;struct dirent *entry;char path[PATH_MAX];int ret = 0;// 打开目录dir = opendir(pathname);if (dir == NULL) {perror("opendir failed");return -1;}// 遍历目录中的所有条目while ((entry = readdir(dir)) != NULL) {if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {continue; // 跳过 "." 和 ".."}// 构造完整的路径snprintf(path, sizeof(path), "%s/%s", pathname, entry->d_name);// 检查是否为目录struct stat statbuf;if (stat(path, &statbuf) == -1) {perror("stat failed");ret = -1;break;}if (S_ISDIR(statbuf.st_mode)) {// 递归删除子目录if (remove_directory(path) == -1) {ret = -1;break;}} else {// 删除文件if (unlink(path) == -1) {perror("unlink failed");ret = -1;break;}}}// 关闭目录closedir(dir);// 删除当前目录if (rmdir(pathname) == -1) {perror("rmdir failed");return -1;}return ret;
}int main() {const char *pathname = "/home/user/newdir";// 尝试删除目录if (remove_directory(pathname) != 0) {return 1;}printf("Successfully removed directory: %s\n", pathname);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/86009.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/86009.shtml
英文地址,请注明出处:http://en.pswp.cn/web/86009.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关于二分和分治的详细讲解(从属于GESP五级)

本章内容 二分 分治 当你把疑惑一劈为二&#xff0c;困境就只剩下一半。 一、二分查找 1. 何谓“二分”&#xff1f; “二分”本质是一种 对单调现象反复折半 的搜索思想。 单调现象&#xff1a;随变量增大&#xff0c;目标状态只会保持“假→真”或“真→假”一次性跃迁…

程序猿成长之路之数据挖掘篇——聚类算法介绍

作为无监督学习算法的基础&#xff0c;学好聚类算法很关键&#xff0c;我之前介绍过kmeans聚类算法&#xff0c;现在系统的介绍一下聚类算法 1. 什么是分类 日常生活中我们会经常见到分类的情况&#xff0c;如家里大扫除时给物品归类&#xff0c;超市货架上商品分类等。分类就…

PostgreSQL 性能优化与集群部署:PGCE 认证培训实战指南

&#xff5c;深夜被数据库报警惊醒&#xff1f; &#xff5c;海量数据查询卡死业务&#xff1f; &#xff5c;主库宕机导致服务中断&#xff1f; 如果你正被这些PostgreSQL生产难题困扰&#xff0c;是时候系统掌握数据库内核优化与高可用架构了&#xff01;深度求索联合PG分会…

Java 对象映射 数据库表映射 工具类 两个对象/表实现映射转换

场景&#xff1a;需要将一个对象的各个字段中的数据映射到另一个对象的字段数据中&#xff0c;或将一个数据库表映射到另一张表中。 本文使用泛型编程实现了一个对象映射功能的工具类。 需要源对象&#xff0c;映射关系map&#xff0c;目标类。由于是动态的类&#xff0c;所以…

Linux离线搭建Jenkins

Linux离线搭建Jenkins(centos7) Jenkins简介: Jenkins只是一个平台&#xff0c;真正运作的都是插件。这就是jenkins流行的原因&#xff0c;因为jenkins什么插件都有&#xff0c;Hudson是Jenkins的前身&#xff0c;是基于Java开发的一种持续集成工具&#xff0c;用于监控程序重…

从零学习linux(2)——管理

一.用户管理 1.用户属性 用户名、口令、用户ID&#xff08;UID&#xff09;、用户主目录&#xff08;HOME&#xff09;、用户shell 2. 3. 4.adduser添加用户 语法&#xff1a;adduser 用户名 如# adduser superw 添加用户名为superw的新用户 5.deluser删除用户 语法&am…

《贵州棒垒球》有什么国家级比赛·棒球1号位

中国国家级棒球比赛盘点 | 小白入门指南 3月 | 中国棒球联赛 (China Baseball League) 国内最高水平职业联赛&#xff0c;各省市职业队角逐冠军&#xff01; 英文&#xff1a;Top-tier professional event with teams nationwide. 5月 | 全国青年棒球锦标赛 (National Youth …

该项目名为“EduPal“,AI推荐

## 完整代码实现 ### 后端代码 (app.py) python import os import json import uuid import requests from datetime import datetime from flask import Flask, render_template, request, jsonify from dotenv import load_dotenv # 加载环境变量 load_dotenv() app …

C++法则15:匹配失败并不是一种错误(Substitution Failure Is Not An Error)。

C法则15&#xff1a;匹配失败并不是一种错误(Substitution Failure Is Not An Error)。 应用例子&#xff1a; SFINAE &#xff1a;关于is_class&#xff0c;is_base_of&#xff0c;C编译器的魔法器&#xff0c;如何实现&#xff0c;is_class&#xff0c;is_base_of。_c is cl…

Ollama客户端 + Docker搭建本地知识库(Mac系统)

一、环境准备 1. 安装Ollama客户端 官网下载&#xff1a;https://ollama.com 验证安装&#xff1a; ollama --version2. 安装Docker Desktop 下载地址&#xff1a;https://www.docker.com/products/docker-desktop 安装后确保Docker状态为"Running" 二、基础搭建…

FastMCP 2.9 版本详解:MCP 原生中间件与类型转换增强

下面我将从三个方面来讲解这个&#xff0c;第一是讲解2.9版本的更新&#xff0c;第二是讲解什么将手动解析底层JSON-RPC 消息&#xff0c;丢失 FastMCP 高层语义&#xff0c;第三是讲一讲&#xff0c;什么叫做中间件。不了解的兄弟们系好安全带&#xff0c;我们准备发车了&…

LTspice仿真6——PWL折线波产生

1.自定义波形 2.自定义波形周期 3.以文件.txt的形式定义折线波 4.通过C语言编程&#xff0c;一系列操作&#xff0c;生成自定义正弦波&#xff08;可自定义性强&#xff09;

FunASR搭建语音识别服务和VAD检测

调整VAD参数 1. 查找VAD模型的配置文件 FunASR中的VAD模型为FSMN-VAD&#xff0c;参数配置类为VADXOptions&#xff0c;可以在以下路径中找到&#xff1a; /workspace/FunASR/runtime/python/onnxruntime/funasr_onnx/utils/e2e_vad.py 其中&#xff0c;VADXOptions类定义了…

多模态大模型(从0到1)

文章目录 一、多模态大模型二、常见模态组合 典型应用场景三、多模态&#xff08;模型 框架&#xff09;1. 多模态模型2. 多模态框架 —— 开源项目推荐&#xff08;可快速上手&#xff09; 四、入门与学习路线1. 理论基础2. 主流多模态模型实战3. 进阶与应用拓展&#x1f4d…

# Vue.js 精确轮播组件实现详解

## &#x1f4d6; 概述 本文详细介绍了一个基于 Vue.js 开发的高精度轮播组件&#xff0c;该组件实现了精确的卡片对齐和平滑滚动效果。组件支持混合布局&#xff08;大卡片网格布局&#xff09;&#xff0c;具备智能位置计算和精确滚动控制功能。 ## ✨ 组件特点 ### &#x1…

将RESP.app的备份数据转码成AnotherRedisDesktopManager的格式

将RESP.app的备份数据转码成AnotherRedisDesktopManager的格式 最近发现了AnotherRedisDesktopManager&#xff0c;这个软件可以直接展示proto数据。 将RESP.app导出的json文件&#xff0c;转码为AnotherRedisDesktopManager的ano文件&#xff08;是一个list转了base64&#xf…

前端基础知识JavaScript系列 - 09(JavaScript原型,原型链 )

一、原型 JavaScript 常被描述为一种基于原型的语言——每个对象拥有一个原型对象 当试图访问一个对象的属性时&#xff0c;它不仅仅在该对象上搜寻&#xff0c;还会搜寻该对象的原型&#xff0c;以及该对象的原型的原型&#xff0c;依次层层向上搜索&#xff0c;直到找到一个…

vue3+ts 使用VueCropper实现剪切图片

效果图&#xff1a; 参考文档&#xff1a; Vue-Cropper 文档Vue-Cropper 文档 安装VueCropper //npm安装 npm install vue-croppernext -d --save//yarn安装 yarn add vue-croppernext 引入组件 在main.ts中全局注册&#xff1a; import VueCropper from vue-cropper; i…

el-table特殊表头样式

el-table特殊表头样式 实现表头是按钮 <el-table-column align"center"><template slot"header"><el-buttonsize"mini"type"primary"icon"el-icon-plus"circleclick"addData"></el-button&g…

el-tree的属性render-content自定义样式不生效

需求是想要自定义展示el-tree的项&#xff0c;官网有一个:render-content属性&#xff0c;用的时候发现不管是使用class还是style&#xff0c;样式都没有生效&#xff0c;还会报一个错&#xff0c;怎么个事呢&#xff0c;后来发现控制台还会报一个错“vue.js:5129 [Vue warn]: …