如何在Linux中获得C/C++中的用户名
How to get the username in C/C++ in Linux?
如何获得实际的"用户名";在程序中不使用环境(getenv
,…)?环境是使用Linux的C/C++。
unistd.h
中定义的函数getlogin_r()
返回用户名。有关详细信息,请参见man getlogin_r
。
其签名为:
int getlogin_r(char *buf, size_t bufsize);
不用说,这个函数在C或C++中也可以很容易地调用。
来源http://www.unix.com/programming/21041-getting-username-c-program-unix.html:
/* whoami.c */
#define _PROGRAM_NAME "whoami"
#include <stdlib.h>
#include <pwd.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
register struct passwd *pw;
register uid_t uid;
int c;
uid = geteuid ();
pw = getpwuid (uid);
if (pw)
{
puts (pw->pw_name);
exit (EXIT_SUCCESS);
}
fprintf (stderr,"%s: cannot find username for UID %un",
_PROGRAM_NAME, (unsigned) uid);
exit (EXIT_FAILURE);
}
只需将主线封装在类中即可:
class Env{
public:
static std::string getUserName()
{
uid_t uid = geteuid ();
struct passwd *pw = getpwuid (uid);
if (pw)
{
return std::string(pw->pw_name);
}
return {};
}
};
仅适用于C:
const char *getUserName()
{
uid_t uid = geteuid();
struct passwd *pw = getpwuid(uid);
if (pw)
{
return pw->pw_name;
}
return "";
}
#include <iostream>
#include <unistd.h>
int main()
{
std::string Username = getlogin();
std::cout << Username << std::endl;
return 0 ;
}
另一种方式是这样-
#include <iostream>
using namespace std;
int main()
{
cout << system("whoami");
}
使用stdio.h
中的char *cuserid(char *s)
。
#include <stdio.h>
#define MAX_USERID_LENGTH 32
int main()
{
char username[MAX_USERID_LENGTH];
cuserid(username);
printf("%sn", username);
return 0;
}
有关更多详细信息,请参阅:
- https://pubs.opengroup.org/onlinepubs/007908799/xsh/cuserid.html
- https://serverfault.com/questions/294121/what-is-the-maximum-username-length-on-current-gnu-linux-systems
通过现代c++规范进行一点工作
static auto whoAmI = [](){ struct passwd *tmp = getpwuid (geteuid ());
return tmp ? tmp->pw_name : "onlyGodKnows";
}
#include <pwd.h>
#include <sys/types.h>
#include <unistd.h>
// Return username or nullptr if unknown.
const char* username() {
const passwd* pw = getpwuid(geteuid());
return pw == nullptr ? nullptr : pw->pw_name;
}
今天我不得不做同样的事情,但不喜欢包含任何特定于操作系统的头。因此,以下是您可以在不使用任何Linux/Windows特定标头的情况下以跨平台方式进行的操作:
#include <stdio.h>
#include <memory>
#include <stdexcept>
#include <array>
#include <regex>
std::string execute_command(std::string cmd)
{
std::array<char, 128> buffer;
std::string result;
#if defined(_WIN32)
#define POPEN _popen
#define PCLOSE _pclose
#elif defined(unix) || defined(__unix__) || defined(__unix)
#define POPEN popen
#define PCLOSE pclose
#endif
std::unique_ptr<FILE, decltype(&PCLOSE)> pipe(POPEN(cmd.c_str(), "r"), PCLOSE);
if (!pipe)
{
throw std::runtime_error("popen() failed!");
}
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr)
{
result += buffer.data();
}
return result;
}
std::string get_current_username()
{
#if defined(_WIN32)
// whoami works on windows as well but it returns the name
// in the format of `computer_nameuser_name` so instead
// we use %USERNAME% which gives us the exact username.
#define USERNAME_QUERY "echo %USERNAME%"
#elif defined(unix) || defined(__unix__) || defined(__unix)
#define USERNAME_QUERY "whoami"
#endif
auto username = execute_command(USERNAME_QUERY);
// this line removes the white spaces (such as newline, etc)
// from the username.
username = std::regex_replace(username, std::regex("\s"), "");
return username;
}
这在Linux和Windows上都很好用,并且与C++11兼容!
在线测试:https://paiza.io/projects/e/xmBuf3rD7MhYca02v5V2dw?theme=twilight
相关文章:
- C++如何通过用户输入删除列表元素
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 如何使用用户输入在C++中正确填充2D数组
- C++MySQL C api用户输入行
- 使用用户定义函数的字符串反转
- 用户定义函数中的指针和输入
- 为什么即使使用-cudart-static进行编译,库用户仍然需要链接到cuda运行时
- 如何只允许用户输入正整数
- C++如何计算用户输入的数字中的偶数位数
- 通过for循环使用用户输入填充列表
- 这是我尝试让用户将值输入到数组中.然后将其隐藏为大量的星号
- 在C++中,我如何接受不同于同一行的用户输入
- 当用户超过按钮点击限制时报告
- Visual C++(VS2017)中用户定义的转换不明确
- 如果用户输入无效,如何使用字符串变量-C++重复输入命令
- C++问题:用户认为数字1-100,程序提出问题不超过6次即可得到答案。无法正确
- 当用户键入分隔符时,停止getline()输入
- 通过错误处理,在C++中可靠地获得用户十六进制输入
- RegGetValue在当前用户下找不到名称
- 函数计算用户按下按钮的频率