(这与其说是学究气的练习,不如说是一个问题,所以就这样吧。)
我已经制作了一个不错的小程序,它是我的 linux 操作系统的原生程序,但我认为它也足以存在于我的 Windows 机器上。因此,我想访问 Windows 的环境变量,MSDN 引用了一个这样的例子:
const DWORD buff_size = 50;
LPTSTR buff = new TCHAR[buff_size];
const DWORD var_size = GetEnvironmentVariable("HOME",buff,buff_size);
if (var_size==0) { /* fine, some failure or no HOME */ }
else if (var_size>buff_size) {
// OK, so 50 isn't big enough.
if (buff) delete [] buff;
buff = new TCHAR[var_size];
const DWORD new_size = GetEnvironmentVariable("HOME",buff,var_size);
if (new_size==0 || new_size>var_size) { /* *Sigh* */ }
else { /* great, we're done */ }
}
else { /* in one go! */ }
这不像使用 getenv 并仅检查空指针那么好(对我来说)。我也不想动态分配内存,因为我只是想让程序在 Windows 和我的 linux 操作系统上运行,这意味着这个 MS 代码必须与 nix 代码很好地配合。进一步来说:
template <class T> // let the compiler sort out between char* and TCHAR*
inline bool get_home(T& val) { // return true if OK, false otherwise
#if defined (__linux) || (__unix)
val = getenv("HOME");
if (val) return true;
else return false;
#elif defined (WINDOWS) || defined (_WIN32) || defined (WIN32)
// something like the MS Code above
#else
// probably I'll just return false here.
#endif
}
因此,我必须在堆上进行普遍分配,或者在调用函数中执行 #ifdef
以释放内存。不是很漂亮。
当然,我可以首先在堆栈上分配“buff”,但是如果在第一次调用 GetEnvironmentVariable 时“buff_size”不够大,我必须创建一个新的 TCHAR[]
.更好,但是如果我是一个书呆子并且不想到处创建多余的数组怎么办?关于更美观的东西的任何想法?
我不是那么知识渊博,所以有人会嫉妒我故意强迫 GetEnvironmentVariable 失败以获得字符串大小吗?有没有人看到以下问题:
const DWORD buff_size = GetEnvironmentVariable("HOME",0,0);
TCHAR buff[buff_size];
const DWORD ret = GetEnvironmentVariable("HOME",buff,buff_size);
// ...
还有其他想法或建议吗? (或者纠正明显的错误?)
更新:下面有很多有用的信息。我认为我想做的最好的选择是使用 static char[]
比如:
inline const char* get_home(void) { // inline not required, but what the hell.
#if defined (__linux) || (__unix)
return getenv("HOME");
#elif defined (WINDOWS) || defined (WIN32) || defined (_WIN32)
static char buff[MAX_PATH];
const DWORD ret = GetEnvironmentVariableA("USERPROFILE",buff,MAX_PATH);
if (ret==0 || ret>MAX_PATH)
return 0;
else
return buff;
#else
return 0;
#endif
}
也许这不是最优雅的方式,但它可能是在 *nix 和 Windows 之间同步我想做的最简单的方式。 (稍后我还会担心 Unicode 支持。)
感谢所有帮助过的人。
原文由 Zorawar 发布,翻译遵循 CC BY-SA 4.0 许可协议
当然,如果您想要 ASCII,请将
wstring
替换为string
和GetEnvironmentVariableW
替换为 —c31feGetEnvironmentVariableA
编辑:您也可以自己创建
getenv
。这有效,因为当然,如果您想保持对 unicode 的支持,那么使用所有这些的宽字符版本可能是一个好主意。