C/C++ Windows和Linux通用的一个函数,从文件路径中 提取 (文件名) 和 (文件后缀)

假如给你一个文件路径,你可以将其中的文件名和文件后缀提取出来嘛?
不会没有关系,此篇博客提供一个函数,即可在Windows环境下调用,也可以在Linux环境下调用,去获取一个文件路径的文件名和文件后缀!


一、返回值 bool 版

需要包含头文件:
#include <stdio.h>
#include <string.h>
#include <string>

代码如下:

/******************************************************************************
 *
 * 功能:
 *		获得 (文件名.后缀) 和 (文件名) 和 (文件后缀),Windows和Linux通用!
 *
 * 参数:
 *		_filePaht:C语言字符指针,文件路径字符串
 *		_fileName:C++字符串引用,获得[(文件名.后缀)|(文件名)]返回
 *		_fileName:C++字符串引用,获得(文件名.后缀)返回
 *		_fileSuffix:C++字符串引用,获得(后缀)返回
 *		_dot:true,后缀带点(.txt);false,后缀不带点(txt);默认值为true
 *
 * 返回值:
 *		成功返回true,失败返回false
 *
 ******************************************************************************/
bool get_fileName_fileSuffix(const char *_filePaht, std::string &_fileNames, std::string &_fileName, std::string &_fileSuffix, bool _dot = true) {

	// 合法性检查
	if (!_filePaht) return false;
	std::string str = _filePaht;
	if (str.empty()) return false;


	// .txt    的情况
	if (str.at(0) == '.') return false;
	// file.   的情况
	if (str.at(str.size() - 1) == '.') return false;
	

	char c = '\0';

// 区分此函数是在Windows环境调用还是Linux环境调用
#if defined (_WIN64) || defined (WIN32) || defined (_WIN32)
	//printf("---Windows---\n");
	c = '\\';
#else
	//printf("---Linux---\n");
	c = '\/';
#endif

	// 去除字符串中的路径,剩下文件名
	std::string filename = strrchr(_filePaht, c) == NULL ? "" : strrchr(_filePaht, c) + 1;
	if (filename == "") {
		/* 说明字符串是file.txt或者file形式 */
		filename = _filePaht;
	
	} else {
		/* 说名字符串是C:\\abc\\file.txt或者C:\\abc\\file形式 */
	}

	// 找到 . 的位置
	size_t _size = filename.rfind(".");
	// 获得文件名,不包含后缀
	_fileName = filename.substr(0, _size);

	// 获得文件后缀
	std::string strsuffix = "";
	if (_size != -1) {	// 不等于-1说明有后缀 file.txt形式

		// true后缀带点,false后缀不带点
		if (_dot == true) {
			strsuffix = filename.substr(_size);     // 文件后缀 .txt

		} else {
			strsuffix = filename.substr(_size + 1);     // 文件后缀 txt
		}
	}
	// 后缀
	_fileSuffix = strsuffix;

	// 获得文件名.后缀(file.txt | file)
	_fileNames = filename;

	return true;
}

具体过程就不解释了,都有详细注释,去看,去理解吧。

  1. 测试Windows路径:
    C:\abc\file.txt
    C:\abc\file
    file.txt
    file

    int main(void) {
    
    	// C:\\abc\\file.txt
    	// C:\\abc\\file
    	// file.txt
    	// file
    
    	std::string fileNames = "";
    	std::string fileName = "";
    	std::string fileSuffix = "";
    	bool suffix = true;
    	bool flag = false;
    
    	//printf("---Windows---\n");
    
    	flag = get_fileName_fileSuffix("C:\\abc\\file.txt", fileNames, fileName, fileSuffix, suffix);
    	printf("str = %s, fileNames = %s   fileName = %s   fileSuffix = %s   flag = %d\n\n", "C:\\abc\\file.txt", fileNames.c_str(), fileName.c_str(), fileSuffix.c_str(), flag);
    
    	flag = get_fileName_fileSuffix("C:\\abc\\file", fileNames, fileName, fileSuffix, suffix);
    	printf("str = %s, fileNames = %s   fileName = %s   fileSuffix = %s   flag = %d\n\n", "C:\\abc\\file", fileNames.c_str(), fileName.c_str(), fileSuffix.c_str(), flag);
    
    	flag = get_fileName_fileSuffix("file.txt", fileNames, fileName, fileSuffix, suffix);
    	printf("str = %s, fileNames = %s   fileName = %s   fileSuffix = %s   flag = %d\n\n", "file.txt", fileNames.c_str(), fileName.c_str(), fileSuffix.c_str(), flag);
    
    	flag = get_fileName_fileSuffix("file", fileNames, fileName, fileSuffix, suffix);
    	printf("str = %s, fileNames = %s   fileName = %s   fileSuffix = %s   flag = %d\n\n", "file", fileNames.c_str(), fileName.c_str(), fileSuffix.c_str(), flag);
    
    	fileNames = "";
    	fileName = "";
    	fileSuffix = "";
    	flag = get_fileName_fileSuffix("", fileNames, fileName, fileSuffix, suffix);
    	printf("str = %s, fileNames = %s   fileName = %s   fileSuffix = %s   flag = %d\n\n", "\"\"", fileNames.c_str(), fileName.c_str(), fileSuffix.c_str(), flag);
    
    	return 0;
    }
    

    运行截图:
    这个是后缀带点(.txt)的测试
    在这里插入图片描述

  2. 测试Linux路径:
    /abc/file.txt
    /abc/file
    file.txt
    file

    int main(void) {
    
    	std::string fileNames = "";
    	std::string fileName = "";
    	std::string fileSuffix = "";
    	bool suffix = false;
    	bool flag = false;
    
    	// /abc/file.txt
    	// /abc/file
    	// /file.txt
    	// file
    	//printf("---Linux---\n");
    
    	flag = get_fileName_fileSuffix("/abc/file.txt", fileNames, fileName, fileSuffix, suffix);
    	printf("str = %s, fileNames = %s   fileName = %s   fileSuffix = %s   flag = %d\n\n", "/abc/file.txt", fileNames.c_str(), fileName.c_str(), fileSuffix.c_str(), flag);
    
    	flag = get_fileName_fileSuffix("/abc/file", fileNames, fileName, fileSuffix, suffix);
    	printf("str = %s, fileNames = %s   fileName = %s   fileSuffix = %s   flag = %d\n\n", "/abc/file", fileNames.c_str(), fileName.c_str(), fileSuffix.c_str(), flag);
    
    	flag = get_fileName_fileSuffix("file.txt", fileNames, fileName, fileSuffix, suffix);
    	printf("str = %s, fileNames = %s   fileName = %s   fileSuffix = %s   flag = %d\n\n", "/file.txt", fileNames.c_str(), fileName.c_str(), fileSuffix.c_str(), flag);
    
    	flag = get_fileName_fileSuffix("file", fileNames, fileName, fileSuffix, suffix);
    	printf("str = %s, fileNames = %s   fileName = %s   fileSuffix = %s   flag = %d\n\n", "/file", fileNames.c_str(), fileName.c_str(), fileSuffix.c_str(), flag);
    
    	return 0;
    }
    

    运行截图:
    这个是后缀不带点(txt)的测试
    在这里插入图片描述


二、返回值 后缀索引 版

第一个版本是两个星期前写好的,后续回来看后,觉得返回值好像不是太友好,于是乎更改了以下版本代码。
返回的是 后缀索引 。

处理过程不变!

需要包含头文件:
#include <stdio.h>
#include <string.h>
#include <string>

/******************************************************************************
 *
 * 功能:
 *		获得 (文件名.后缀) 和 (文件名) 和 (文件后缀),Windows和Linux通用!
 *
 * 参数:
 *		_filePaht:			C语言字符指针,文件路径字符串
 *		_fullFileName:		C++字符串引用,获得[(文件名.后缀) 或 (文件名)]返回
 *		_fileName:			C++字符串引用,获得(文件名.后缀)返回
 *		_fileSuffix:		C++字符串引用,获得(后缀)返回
 *		_dot:				true,后缀带点(.txt);false,后缀不带点(txt);默认值为true
 *
 * 返回值:
 *		有后缀返回"."的索引;没有后缀则返回-1
 *
 ******************************************************************************/
int get_fileName_fileSuffix(const char *_filePaht, std::string &_fullFileName, std::string &_fileName, std::string &_fileSuffix, bool _dot = true) {

	// 合法性检查
	if (!_filePaht) return -1;
	std::string str = _filePaht;
	if (str.empty()) return -1;

	// .txt    的情况
	if (str.at(0) == '.') return -1;
	// file.   的情况
	if (str.at(str.size() - 1) == '.') return -1;



	char c = '\0';

	// 区分此函数是在Windows环境调用还是Linux环境调用
#if defined (_WIN64) || defined (WIN32) || defined (_WIN32)
	//printf("---Windows---\n");
	c = '\\';
#else
	//printf("---Linux---\n");
	c = '\/';
#endif

	// 去除字符串中的路径,剩下文件名
	std::string filename = strrchr(_filePaht, c) == NULL ? "" : strrchr(_filePaht, c) + 1;
	if (filename == "") {
		/* 说明字符串是file.txt或者file形式 */
		filename = _filePaht;

	} else {
		/* 说名字符串是C:\\abc\\file.txt或者C:\\abc\\file形式 */
	}

	// 找到 . 的位置
	size_t _size = filename.rfind(".");
	// 获得文件名,不包含后缀
	_fileName = filename.substr(0, _size);

	// 获得文件后缀
	std::string strsuffix = "";
	if (_size != -1) {	// 不等于-1说明有后缀 file.txt形式

		// true后缀带点,false后缀不带点
		if (_dot == true) {
			strsuffix = filename.substr(_size);     // 文件后缀 .txt

		} else {
			strsuffix = filename.substr(_size + 1);     // 文件后缀 txt
		}
	}
	// 后缀
	_fileSuffix = strsuffix;

	// 获得文件名.后缀(file.txt | file)
	_fullFileName = filename;

	return _size;
}

测试:

int main(void) {

	std::string str = "abc.jpg";
	//std::string str = ".abcjpg";
	//std::string str = "abcjpg.";
	std::string fullFilename, filename, fileSuffix;
	int r = get_fileName_fileSuffix(str.c_str(), fullFilename, filename, fileSuffix, true);
	printf("r = %d\n", r);
	printf("fullFilename = %s   filename = %s   fileSuffix = %s\n", fullFilename.c_str(), filename.c_str(), fileSuffix.c_str());


	return 0;
}

运行截图:
在这里插入图片描述


总结

本人在做项目时经常需要在一个路径中提取出文件名和文件路径,但是在项目中写的是零散的代码,所以在这里总结成一个函数,通过这个函数去获取就方便多了,而且windows和linux通用!(废了两个三个小时写代码、测试和写博客,值得!)

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cpp_learners

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值