在C中引用程序名时的最佳实践

cvxl0en2  于 2023-05-16  发布在  其他
关注(0)|答案(8)|浏览(93)

在提到程序名称时,什么是最佳实践?我见过:

#define PROGRAM_NAME "myprog"
printf("this is %s\n", PROGRAM_NAME);

以及:

printf("this is %s\n", argv[0]);

我知道,当程序不是从$PATH调用时,第二种方法将给予我./myprog而不是myprog,第一种方法将保证程序名称的一致性。
但是,还有什么其他的东西,使一种方法上级另一种方法吗?

ctzwtxfj

ctzwtxfj1#

当您有多个链接时,第二种方法更上级。在 *nix系统中,有时行为取决于你如何调用程序。因此,对程序名进行硬编码显然是个问题--它永远无法检查这一点。

igsr9ssn

igsr9ssn2#

我试着把两个世界的最好的:

char const * program_name;

int main(int argc, char **argv) {
   program_name = argv[0];
   //...
}

如果你需要program_name在其他文件中可用,你可以这样声明它:

extern char const * program_name;

我声明“char const *”是因为我希望它是一个指向const数据的指针。我不确定我做对了这部分。

pbpqsu0x

pbpqsu0x3#

我通常使用argv[0],或者如果可能的话使用basename(argv[0])。从用户的观点来看,我认为如果他们重命名或硬链接一个可执行文件(或者其他人为他们这样做),那么他们希望来自它的消息以他们正在使用的名称出现,而不是以他们可能知道或不知道的其他名称编译。
类似地,如果你将来发现你想用不同的名字和不同的选项编译你的程序,以给予不同的版本,你想在#define周围 Package 一个#ifndef,并确保它是通过编译器命令行定义的吗?-DPROGRAM_NAME=myprog_demo,或者你只是想做它,它的工作?
例外情况可能是,如果您的使用说明是从手册页或其他文档中摘录的,那么您可能确实希望将程序名硬连接到其中。但是你可能也不会使用#define
但是,实现不需要提供argv[0],因此为了获得最佳可移植性,也要处理这种情况。同样,如果您的系统不提供它,那么用户实际上也不会在任何类型的终端上看到消息。
顺便说一下:

#define PROGRAM_NAME "myprog"
puts("this is " PROGRAM_NAME);
hi3rlvi2

hi3rlvi24#

第二种方法也可以给予你像/usr/bin/myprog这样的字符串,如果你这样执行的话; basename应该给予可执行文件的名称(您可以将其视为程序的名称)。除非它是符号链接的(在这种情况下,你有链接的名称。。其可用于在程序行为中进行某种选择)。
第一种方法将程序名“固定”为程序员想要的,不管用户如何重命名可执行文件或符号链接(甚至是硬链接)

1wnzp6jl

1wnzp6jl5#

它并不能确切地回答你关于编程最佳实践的问题,但我认为你也应该记住什么对用户最好。我个人更喜欢使用argv[0]引用自己的程序,即。我调用的命令,而不是编码器在程序中硬编码的随机名称。以下是一些硬编码名称令人讨厌或至少没有帮助的例子:

  • 我创建了一个程序的链接
  • 出于某种原因我重命名了二进制文件
  • 我在$PATH的不同目录中有多个具有相同基本名称的可执行文件
  • 一个程序会提示我其他调用它的方法,例如。在“使用”消息中

我唯一喜欢硬编码程序名的情况是当我使用GUI应用程序时。我不希望看到“~/foo/bar.pl“作为窗口标题。

6rqinv9w

6rqinv9w6#

当您手头没有argv时,前者上级后者。

#define PROGRAM_NAME "myprog"

void salute()
{
     // no argv available 

     printf("Hello from %s\n", PROGRAM_NAME );
}

void main( int argc, char** argv ) 
{
     salute();
}
vtwuwzda

vtwuwzda7#

取决于argv是否在作用域中...

hzbexzde

hzbexzde8#

全局变量在正确使用时是很好的。可能比#define更好,因为至少在调试时可以轻松地检查它们。
basename,然而,引起了我的一些怀疑。

static inline char *my_basename(char const *name) // neither GNU nor POSIX...
{
    char *b = strrchr(name, '/');
    if (b)
        return b + 1;
    return (char*)name;
}

/* ... */

char *program_name;

/* ... */

void salute()
{
     // no argv available 

     printf("Hello from %s\n", program_name);
}

int main(int argc, char* argv[]) 
{
     program_name = my_basename(argv[0]);
     salute();
     return 0;
}

相关问题