C/C++ getcwd 获取项目的运行路径

在Linux下做QT项目时,需要获取项目的运行路径,于是用getcwd函数进行获取,然后在Windows下进行测试,发现获取到的是程序的项目路径,即代码文件路径,然后再Linux QT中测试,获取到的又是运行路径,这就很纳闷了。经过再三测试,终于发现了原因!


一、

头文件:
在unix下是unistd.h,VS下是direct.h

代码:

#include <stdio.h>
#include <string>

// 区分此函数是在Windows环境调用还是Linux环境调用
#if defined (_WIN64) || defined (WIN32) || defined (_WIN32)

//printf("---Windows---\n");
#include <direct.h>

#else

//printf("---Linux---\n");
#include <unistd.h>

#endif



/******************************************************************************
 *
 * 功能:
 *		获得当前程序的工作路径(绝对路径),即运行路径!
 *
 * 注意:
 *		头文件在unix下是unistd.h,VS下是direct.h,应该依编程者的环境而定.
 *		这里解释一下运行路径,即是程序开始运行的路径,例如:
 *			1.如果是在Windows环境的VS编译器中运行项目,则返回的是项目路径,
 *			  即代码文件路径(.h和.cpp路径),因为是在编译器中运行的项目,所以
 *			  程序的运行路径也是才项目路径中开始运行的。
 *			2.如果是在Windows环境,运行已经编译好的.exe程序,则返回的是当前
 *			  .exe程序所在的路径,因为是在当前路径所运行的!
 *			3.在Linux环境,返回的都是可执行程序的路径!
 *
 * 参数:
 *		无.
 *
 * 返回值:
 *		成功返回程序的工作路径(绝对路径);失败返回空串
 *
 ******************************************************************************/
std::string getOperationFilePath() {

	char *buffer = NULL;

	// 区分此函数是在Windows环境调用还是Linux环境调用
#if defined (_WIN64) || defined (WIN32) || defined (_WIN32)

	// 获取项目的工作路径
	buffer = _getcwd(NULL, 0);

#else

	// 获取项目的工作路径
	buffer = getcwd(NULL, 0);

#endif

	if (buffer) {
		std::string path = buffer;
		free(buffer);
		return path ;
	}

	return "";
}

测试运行:

int main(void) {

	printf("getOperationFilePath = %s\n", getOperationFilePath().c_str());

	system("pause");
	return 0;
}
  1. 在VS中运行截图
    在这里插入图片描述

  2. 直接运行.exe截图
    在这里插入图片描述

解释上面提到的问题:
这里解释一下运行路径,即是程序开始运行的路径,例如:

  1. 如果是在Windows环境的VS编译器中运行项目,则返回的是项目路径,
    即代码文件路径(.h和.cpp路径),因为是在编译器中运行的项目,所以
    程序的运行路径也是才项目路径中开始运行的。
  2. 如果是在Windows环境,运行已经编译好的.exe程序,则返回的是当前
    .exe程序所在的路径,因为是在当前路径所运行的!
  3. 在Linux环境,返回的都是可执行程序的路径!

二、

Windows有一个api可以直接获得项目的运行路径,不用区分是在项目中运行还是.exe运行

头文件:
#include < Windows.h >

#include <Windows.h>

int main(void) {

	char path[1024] = { 0 };
	GetModuleFileNameA(NULL, path, MAX_PATH);		// 获取到完整路径,如:E:\Tools\qq.exe
	*strrchr(path, '\\') = '\0';					// 截取路径,如:E:\Tools

	printf("paht = %s\n", path);

	system("pause");
	return 0;
}

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

如果把代码:*strrchr(path, ‘\’) = ‘\0’; // 截取路径,如:E:\Tools
注释掉,则可以获得全路径:
在这里插入图片描述


三、

如果第一种方式没法正确获取的话,可以尝试使用此种方式:

头文件: #include < unistd.h >

linux系统中有个符号链接:/proc/self/exe它代表当前程序,可以用readlink读取它的源路径就可以获取当前程序的绝对路径了。

std::string getOperationFilePath() {
    char buf[256] = { 0 };

    int ret = readlink("/proc/self/exe", buf, 256);
    if (ret < 0) {
        printf("%d: readlink error:%s", __LINE__, strerror(errno));
        return "";
    }

    *strrchr(buf, '/') = '\0';      // 去掉可执行程序名  /tmp/test/a.exe    ==>     /tmp/test

    return buf;
}

总结
这也是一个小小的细节问题,也有点小坑,今天这个坑我踩过,下次就不会再踩了。
也希望可以帮助看到这篇博客的朋友,跳过此坑!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

cpp_learners

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

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

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

打赏作者

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

抵扣说明:

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

余额充值