相对路径转绝对路径

整理代码的时候需要把用到的模型文件都放到工程目录下, 但自己程序中使用的读取模型的函数都需要绝对路径, 因此需要先有相对路径转绝对路径的操作.

参考材料
1. C++跨文件共享全局变量
2. C语言与C++中static,extern的用法及区别总结

首先利用getcwd函数获取当前工程的绝对路径,

#include <direct.h>
char *buffer;
//也可以将buffer作为输出参数
if ((buffer = getcwd(NULL, 0)) == NULL)
{
    perror("getcwd error");
}
else
{
    std::string input(buffer);
    pathChange(input+"\\..\\..\\");
    free(buffer);
}

因为自己清楚model文件夹放在外边, 所有可以看到上面的代码含有”\\..\\..\\”, pathChange函数返回当前的绝对路径经”\\..\\..\\”处理后的结果,

void pathChange(string input) {
    vector<string> inputpath, outputpath;
    string tmp;
    for (int i = 0; i < input.size(); i++) {   //将input字符串按‘/’分开存储到inputpath 
	if (input[i] != '\\') {			//向量中。 注意:第一个为空字符串! 
	    tmp += input[i];
	}
	else {
	    inputpath.push_back(tmp);
	    tmp.clear();
	}
    }

    while (!inputpath.empty()) {			//判断vector最后一个数据是否为“..”,若 
	if (inputpath.back() != "..") {	//是,则连续2次删除尾数据,若否,则将尾数 
	    tmp = inputpath.back();		//据存到outputpath中,并删除inputpath中的 
	    outputpath.push_back(tmp);	//尾数据。 
	    inputpath.pop_back();
	}
	else {
	    int pop_num = 0;
	    int end = inputpath.size() - 1;
	    while (inputpath[end] == "..") {
		pop_num += 2;
		--end;
	    }
	    for (int i = 0; i < pop_num; ++i) inputpath.pop_back();
	}
    }

    projectPath = "";
    for (auto iter = outputpath.rbegin(); iter != outputpath.rend(); iter++) projectPath += (*iter) + "\\";
}

值得注意的是, 一开始我的pathChange的返回类型是string, 然鹅string对象一般不能做返回值的, 在跨模块调用时候会出问题, 直接返回string对象一般会是空, 汗…… 因为string里面的构造函数在堆空间动态申请了内存, 不属于栈变量, 函数结束时会调用string的构造函数, 析构函数里释放了在堆空间申请的内存.

还有需要注意的一点是projectPath是另外一个文件中定义的变量, 貌似是第一次使用extern关键字=。= 稍稍记录一下extern和static的用法.

下面的小栗子涉及到三个文件test.h, test.cpp, main.cpp.

// test.h
#ifndef TEST_H
#define TEST_H

#include <iostream>
#include <string>
#include <vector>

extern int global_v;

void modify();

void print();

#endif
// test.cpp
#include "test.h"

using namespace std;

int global_v = 1;

void modify()
{
    global_v++;
    cout << "in test, value increases to " << global_v << endl;
}

void print()
{
    cout << "in test, value is " << global_v << endl;
}
// main.cpp
#include "test.h"

using namespace std;

int main()
{
    cout << "in main function, initial global value is " << global_v << endl;

    modify();
    print();

    return 0;
}

static
当我们同时编译多个文件时, 所有未加static前缀的全局变量和函数都具有全局可见性. static可以用作函数和变量的前缀, 对于函数来讲,static的作用仅限于隐藏. 利用这一特性可以在不同的文件中定义同名函数和同名变量, 而不必担心命名冲突.

extern
extern则是告诉编译器这个变量或函数在其他文档里已被定义了. 另外用法是当C和C++混合编程时假如c++调用的是c源文档定义的函数或变量, 那么要加extern来告诉编译器用c方式命名函数:

extern "C"  //在c++文档里调用c文档中的变量
{
   int j;
   void callme();
}
int main()
{
   callme();
}

因此, static的设计法则是:
A. 若全局变量仅在单个C文档中访问, 则能够将这个变量修改为静态全局变量, 以降低模块间的耦合度;
B. 若全局变量仅由单个函数访问, 则能够将这个变量改为该函数的静态局部变量, 以降低模块间的耦合度;
C. 设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时, 需要考虑重入问题.

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注