4

对于 C/C++,似乎没有可移植的函数来获取 Linux/Posix 和 Windows 中的用户名。实现这一目标的最简单但最健壮的可移植代码是什么?

在 Linux 中,似乎总是定义 USER 环境变量,而 Windows 似乎定义了 USERNAME 变量。依靠 getenv 可以避免包含 windows.h 并最小化预处理器语句:

char * user_name = getenv("USER");
if (!user_name) {
     user_name = getenv("USERNAME");
}

但这种方法是否稳健?还是我对另一种解决方案一无所知?而且我对iOS也一无所知...

4

4 回答 4

4

使用环境变量查找用户名是很不靠谱的:

我将您的代码扩展为:

#include <iostream>

int main()
{
    char * user_name = getenv("USER");
    std::cout << user_name << std::endl;
}

并做到了:

$ whoami
MatsP
$ g++ -Wall -std=c++0x getenv.cpp 
$ ./a.out
MatsP
$ export USER=DonaldDuck
$ ./a.out
DonaldDuck

所以,我肯定会建议,如果用户名对你的代码很重要,那么你应该使用系统特定的函数来获取用户名。如果它对您的代码不重要,请在安装时询问,不要尝试使用任何系统函数来获取用户名。

(在回答您的实际问题时,是的,我认为 iOS 具有与USER环境变量相同的功能 - 尽管我不确定 iPhone 上是否存在有意义的用户)。

于 2013-08-30T11:12:54.933 回答
2

没有便携式解决方案。

在 Linux(和一般的 Unix)下,“用户”是一个数字,可以有多个不同的名称。用于getuid获取 id,然后 getpwuid获取其中一个名称。或用于getlogin获取用户用于登录的名称(但这仅在进程具有控制终端时才有效)。如果您想获取用户已知的所有 名称,则必须使用 迭代getpwent,检查pw_uid返回的每个条目的字段。

保证使用环境变量。在许多情况下,不会设置环境变量,即使设置了,也不能保证它是正确的。

Windows有一个功能GetUserName;不过,我对此了解不多。

于 2013-08-30T11:27:27.037 回答
1

用户概念与操作系统甚至系统有关,与语言无关。

由于周围有无数不同的系统,唯一可行的方法是将自己限制在要支持的系统列表中。

存在可以帮助您实现可移植性的软件,例如用于类 Unix 系统(以及在一定程度上是 Windows)的 GNU 自动工具。

于 2013-08-30T11:13:15.657 回答
-1

你是对的 - 没有便携的方法可以做到这一点。有两种解决方案:使用适当的 ifdef 集在窗口上使用一个代码,在 linux 上使用另一个代码。

另一种方法是使用工厂来完成,它会返回一个抽象对象或指向特定于系统的函数的指针。工厂应检测系统并返回正确的功能/类

于 2013-08-30T11:08:48.660 回答