我将创建的程序将获取UNIX / Linux系统上当前登录的用户名并显示欢迎消息。代码所做的只是执行:
Welcome user@hostname:~/Dev/cpp$
不输出流的其余部分。我需要做什么才能输出剩下的部分?我应该使用其他功能而不是这个吗?我不确定我是否应该使用getenv()。
我想我可以使用正则表达式或其他东西来获取用户名,但这并不能解决问题,尽管无论如何都不会输出流的其余部分。
#include <iostream>
#include <stdlib.h>
int main() {
std::cout << "Welcome " << getenv("USERNAME") << " to APP_NAME. To get available commands use --help" << std::endl;
return 0;
}
答案 0 :(得分:2)
问题是你在没有设置USERNAME
变量的环境中执行程序(这并不让我感到惊讶)。因此,std::getenv
return
为nullptr
并将此未经检查的流式传输到std::cout
会产生未定义的行为,在您的情况下,会截断流。您看到的user@hostname:~/Dev/cpp$
不是由您的程序生成的,而是您的普通shell提示最终处于一个有趣的位置,因为程序突然结束而没有输出最终的新行。
您应该在使用之前测试return
值。
#include <cstdlib>
#include <iostream>
int
main()
{
if (const auto user = std::getenv("USERNAME"))
std::cout << "Hello, " << user << "\n";
else
std::cout << "Hello, whoever you may be.\n";
}
无论如何,这不是您应该如何获取当前登录用户的用户名。如果要使用环境(不可靠),则应使用USER
变量。一个可能更强大的解决方案是使用POSIX指定的getlogin
函数,并通过<unistd.h>
提供。请注意,getlogin
也可能失败(return
一个nullptr
),因此您仍然应该有备用策略。
答案 1 :(得分:1)
唯一可能的原因是执行程序时环境变量USERNAME
不存在。然后getenv
函数返回nullptr
(由@ 5gon12eder建议),并通过在输出流中注入nullptr
来调用未定义的行为。在你的例子中,它只是结束输出(就像它在字符串中插入一个null一样),在我自己的一个中,如果引发一个SIGSEGV。
您应该确保环境变量存在:
int main() {
const char *name = getenv("USERNAME");
if (name == std::nullptr) { name = "unknown guest"; }
std::cout << "Welcome " << name << " to APP_NAME. To get available commands use --help" << std::endl;
return 0;
}