【问题标题】:Portable way to get user name获取用户名的便携方式
【发布时间】:2013-09-03 02:09:00
【问题描述】:

对于 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也一窍不通……

【问题讨论】:

标签: c++ portability getenv


【解决方案1】:

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

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

【讨论】:

  • 你不需要工厂;只需声明一个返回std::string 的函数,并在两个(或更多)不同的源文件中实现它。您实际编译的源文件取决于系统。
【解决方案2】:

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

我将您的代码扩展为:

#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 上是否存在有意义的用户)。

【讨论】:

  • 如果用于将游戏分数保存在每个用户的单独文件中,则环境变量可能是可接受的解决方案。它确实允许一个用户以不同的名称进行操作。但是游戏程序可能不会在变量根本不可用的上下文中被调用。
【解决方案3】:

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

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

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

【讨论】:

    【解决方案4】:

    没有可移植的解决方案。

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

    环境变量的使用是保证的。在许多 上下文,环境变量不会被设置,即使它 就是,不保证是正确的。

    Windows有一个函数GetUserName;我知道的不多 然而,关于它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-11
      • 2010-12-25
      • 1970-01-01
      • 1970-01-01
      • 2010-12-12
      • 1970-01-01
      相关资源
      最近更新 更多