2013-08-30 10 views
3

Для 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 ...

+0

Посмотрите: http://stackoverflow.com/questions/8953424/get-user-name-c-linux –

ответ

2

Нет портативного решения.

Под Linix (и Unix вообще), «пользователь» является числом, и может иметь несколько разных имен. Используйте getuid, чтобы получить идентификатор, затем getpwuid, чтобы получить одно из имен. Или используйте getlogin, чтобы получить имя пользователя, используемого для входа (но это будет работать только в том случае, если процесс имеет управляющий терминал). Если вы хотите получить все имен пользователя, как известно, под землей, вам придется перебирать с помощью getpwent, проверяя pw_uid поле для каждой записи вернулся.

Использование переменной окружения не гарантировано. Во многих контекстах переменная среды не будет установлена, и даже если это , это не будет гарантировано.

Windows имеет функцию GetUserName; Однако я не знаю слишком много об этом.

0

Вы правы - нет никакого портативного способа сделать это. Для этого есть два решения: используйте правильный набор ifdef для использования одного кода в окне, а другой - для linux.

Другой способ - сделать это с фабрикой, которая вернет вам абстрактный объект или указатель на функцию, которая будет специфичной для системы. Завод должен определять систему и вернуть правильную функцию/класс

+1

Вам не нужен завод; просто объявите функцию, возвращающую 'std :: string', и реализуем ее в двух (или более) разных исходных файлах. Какой исходный файл, который вы фактически компилируете, будет зависеть от системы. –

3

Использование переменных окружения, чтобы найти имя пользователя очень ненадежны:

я расширил свой код на этот:

#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 

Итак, я бы определенно предположил, что если имя пользователя имеет какое-либо значение для вашего кода, то вы должны использовать системную функцию для получения userna меня. Если это не важно для вашего кода, спросите время установки или некоторые такие, и не пытайтесь использовать какую-либо системную функцию для извлечения имени пользователя.

(В ответ на ваш реальный вопрос, да, я бы подумал, что iOS имеет ту же функциональность переменной окружения USER - хотя я не уверен, что есть значимый пользователь на iPhone).

+0

Если использование для чего-то похожее на сохранение игровых баллов в отдельных файлах для каждого пользователя, переменная окружения, вероятно, является приемлемым решением. Это позволяет одному пользователю работать под разными именами. Но игровая программа, вероятно, не будет вызываться в контекстах, где переменная вообще недоступна. –

1

Концепция пользователя связана с операционной системой или даже с системой, а не с языком.

Поскольку существует множество разных систем, единственный возможный подход - ограничить себя списком систем, которые вы хотите поддержать.

Существует программное обеспечение, которое может помочь вам достичь переносимости, например, GNU autotools для Unix-подобных систем (и в определенной степени Windows).

Смежные вопросы