C/C++获取当前文件夹路径和文件名
文件夹路径获取
头文件
unistd.h是unix std的意思,是POSIX标准定义的unix类系统定义符号常量的头文件, 包含了许多UNIX系统服务的函数原型。
#include <unistd.h>getcwd()
该函数的功能是返回当前 工作目录的绝对路径到一个字符数组中(即参数buf)。该路径中不能包含符号链接组件。
注意此函数获取的是当前执行程序的终端路径,不一定是可执行程序所在路径。
比如可执行程序所在路径为
/foo/bar/test,我在/foo路径下执行./bar/test,则getcwd获取到的路径是/foo,并不是可执行程序路径。
char* getcwd(char* buf, size_t size);buf:保存当前目录的缓冲区
size:在现代linux 中,buf 的长度至少可以为255 字节
返回值:成功返回指向当前目录的指针,和buf 的值一样,错误返回NULL。
#include <cstdio>
#include <unistd.h>
#define PATH_SIZE 255
int main()
{
char path[PATH_SIZE];
if (!getcwd(path, PATH_SIZE))
{
perror("Fail to get current path!");
return 0;
}
printf("path: %s\n", path);
return 0;
}这样会将工作目录的绝对路径复制到buf所指向的空间中,但如果路径长度大于size,则会返回NULL,错误代码为ERANGE.所以我们在定义path的时候得定义的足够大,但这样又会使得内存浪费,Linux的文件名长度限制为255个英文字符,理论上绝对路径的大小应该可以足够大,故而这样使用总有返回NULL的时候,所以getcwd()个我们提供了下面的一种用法:
#include <cstdio>
#include <cstdlib>
#include <unistd.h>
int main(void)
{
char *path = NULL;
path = getcwd(NULL, 0);
puts(path);
free(path);
return 0;
}可以采取令 buf 为 NULL并使 size 为零来使 getcwd 调用 malloc 动态给 buf 分配,但是这种情况要特别注意使用后释放缓冲以防止内存泄漏。
get_current_dir_name()
getcwd()函数需要考虑缓冲区占用字节大小,比较麻烦。get_current_dir_name()函数可以更便捷,其用法如下:
char *get_current_dir_name(void);参数:无
返回值:成功返回指向可执行文件所在目录的指针,错误返回NULL。
#include <cstdio>
#include <cstdlib>
#include <unistd.h>
int main(int argc, char **argv)
{
char *path;
path = get_current_dir_name();
puts(path);
free(path);
return 0;
}get_current_dir_name()函数返回的路径也是通过malloc函数动态的分配的内存,因此使用完其返回值后也要记得对返回值进行free()操作。
readlink()
linux系统中有个符号链接:/proc/self/exe 它代表当前程序,所以可以用readlink读取它的源路径就可以获取当前程序的绝对路径。
ssize_t readlink(const char *path, char *buf, size_t bufsiz);函数说明:readlink()会将参数path的 符号链接内容存储到参数buf所指的内存空间,返回的内容不是以\0作字符串结尾,但会将字符串的字符数返回,这使得添加\0变得简单。
若参数bufsiz小于符号连接的内容长度,过长的内容会被截断。如果 readlink 第一个参数指向一个文件而不是符号链接时,readlink 设置errno 为 EINVAL 并返回 -1。 readlink()函数组合了open()、read()和close()的所有操作。
返回值 :执行成功则返回字符串的字符数,失败返回-1, 错误代码存于errno
#include <unistd.h>
#include <stdio.h>
int main(int argc , char* argv[])
{
char buf[1024] = { 0 };
int n = readlink("/proc/self/exe" , buf , sizeof(buf));
if( n > 0 && n < sizeof(buf))
{
printf("%s\n" , buf);
}
return 0;
}封装函数
#include <iostream>
#include <unistd.h> // 函数所在头文件
using namespace std;
int getCurrentPath(char *path)
{
#ifdef _WIN32
char buf[MAX_PATH];
// 获取当前执行程序的完整路径
GetModuleFileName(NULL, buf, MAX_PATH);
// 去掉可执行程序的名字,从而得到可执行程序的工作目录
(strrchr(buf, '\\'))[1] = '\0';
sprintf(path, "%s", buf);
#else
char *buf = get_current_dir_name();
sprintf(path, "%s/", buf);
free(buf); // 一定记得free,因为是由get_current_dir_name()函数动态分配的内存
#endif
return 0;
}
int main()
{
char buff[1024];
getCurrentPath(buff);
puts(buff);
return 0;
}获取某一存在目录中所有文件名字(包括扩展名)
在Linux系统中读取指定目录下所有文件名的实现步骤主要分三步:
- 打开文件目录opendir()
- 读取文件信息readdir()
- 关闭文件目录closedir()
头文件
#include <sys/types.h>
#include <dirent.h>打开文件目录opendir
DIR *opendir(const char *name);
DIR *fdopendir(int fd);- opendir() 函数根据目录路径打开一个目录流,并返回一个目录流(DIR)指针。这个指针指向目录的首地址。
- fdopendir()函数和opendir()函数类似,只是它是根据文件操作流fd(即常用的文件读取),打开的目录,然后同样是返回目录流指针。
#include <iostream>
#include <sys/types.h>
#include <dirent.h>
using namespace std;
int main(){
// 1、打开文件目录
DIR* dirStream;
const char* path = "/home/XX/code/";
dirStream = opendir(path);
// 2、接下来是读取文件信息
// ...
return 0;
}读取文件信息
#include <dirent.h> // 所在头文件
struct dirent *readdir(DIR *dirp);函数描述:该函数根据打开的目录流指针dirp,返回一个dirent结构体指针。如果在目录流的结尾,那么该指针为空。否则就是表示由dirp指针指向的目录流的下一个目录条目
struct dirent
{
__ino_t d_ino; /*inode number */ // 节点号索引
__off_t d_off; /*offset to this dirent */ // 在目录文件中的偏移
unsigned short int d_reclen; /*length of this d_name */ // 这个文件的名字长度
unsigned char d_type; /*the type of d_name */ // 文件类型
char d_name[256]; /*file name(null-terminated) */ // 这个是文件名
};#include <iostream>
#include <sys/types.h>
#include <dirent.h>
#include <string>
#include <vector>
using namespace std;
int main()
{
// 1、打开文件目录
DIR *dirStream;
const char *path = "/home/qiuyeyijian/workspace/Test";
dirStream = opendir(path);
// 2、接下来是读取文件信息
struct dirent *dirInfo;
vector<string> name;
while ((dirInfo = readdir(dirStream)) != 0)
{
cout << "Value test: " << dirInfo->d_name << endl;
name.push_back(dirInfo->d_name);
} // 注意此时dirStream 已经指向文件尾了
// 3、最后关闭文件目录
closedir(dirStream);
return 0;
}其他
#include <sys/types.h>
#include <dirent.h>
long telldir(DIR *dirp); //返回与目录流dirp相关联的当前位置(地址)
void seekdir(DIR *dirp, long loc);// 设置目录流dirp指向loc,其中参数loc必须是telldir()函数返回的地址。设置之后下次调用readdir函数将从该位置开始读
void rewinddir(DIR *dirp); // 该函数是将目录流指针dirp重置到开始的位置(地址)
秋叶依剑