在提到程序名称时,什么是最佳实践?我见过:
#define PROGRAM_NAME "myprog" printf("this is %s\n", PROGRAM_NAME);
以及:
printf("this is %s\n", argv[0]);
我知道,当程序不是从$PATH调用时,第二种方法将给予我./myprog而不是myprog,第一种方法将保证程序名称的一致性。但是,还有什么其他的东西,使一种方法上级另一种方法吗?
$PATH
./myprog
myprog
ctzwtxfj1#
当您有多个链接时,第二种方法更上级。在 *nix系统中,有时行为取决于你如何调用程序。因此,对程序名进行硬编码显然是个问题--它永远无法检查这一点。
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数据的指针。我不确定我做对了这部分。
pbpqsu0x3#
我通常使用argv[0],或者如果可能的话使用basename(argv[0])。从用户的观点来看,我认为如果他们重命名或硬链接一个可执行文件(或者其他人为他们这样做),那么他们希望来自它的消息以他们正在使用的名称出现,而不是以他们可能知道或不知道的其他名称编译。类似地,如果你将来发现你想用不同的名字和不同的选项编译你的程序,以给予不同的版本,你想在#define周围 Package 一个#ifndef,并确保它是通过编译器命令行定义的吗?-DPROGRAM_NAME=myprog_demo,或者你只是想做它,它的工作?例外情况可能是,如果您的使用说明是从手册页或其他文档中摘录的,那么您可能确实希望将程序名硬连接到其中。但是你可能也不会使用#define。但是,实现不需要提供argv[0],因此为了获得最佳可移植性,也要处理这种情况。同样,如果您的系统不提供它,那么用户实际上也不会在任何类型的终端上看到消息。顺便说一下:
argv[0]
basename(argv[0])
#define
#ifndef
-DPROGRAM_NAME=myprog_demo
#define PROGRAM_NAME "myprog" puts("this is " PROGRAM_NAME);
hi3rlvi24#
第二种方法也可以给予你像/usr/bin/myprog这样的字符串,如果你这样执行的话; basename应该给予可执行文件的名称(您可以将其视为程序的名称)。除非它是符号链接的(在这种情况下,你有链接的名称。。其可用于在程序行为中进行某种选择)。第一种方法将程序名“固定”为程序员想要的,不管用户如何重命名可执行文件或符号链接(甚至是硬链接)
/usr/bin/myprog
1wnzp6jl5#
它并不能确切地回答你关于编程最佳实践的问题,但我认为你也应该记住什么对用户最好。我个人更喜欢使用argv[0]引用自己的程序,即。我调用的命令,而不是编码器在程序中硬编码的随机名称。以下是一些硬编码名称令人讨厌或至少没有帮助的例子:
我唯一喜欢硬编码程序名的情况是当我使用GUI应用程序时。我不希望看到“~/foo/bar.pl“作为窗口标题。
6rqinv9w6#
当您手头没有argv时,前者上级后者。
argv
#define PROGRAM_NAME "myprog" void salute() { // no argv available printf("Hello from %s\n", PROGRAM_NAME ); } void main( int argc, char** argv ) { salute(); }
vtwuwzda7#
取决于argv是否在作用域中...
hzbexzde8#
全局变量在正确使用时是很好的。可能比#define更好,因为至少在调试时可以轻松地检查它们。basename,然而,引起了我的一些怀疑。
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; }
8条答案
按热度按时间ctzwtxfj1#
当您有多个链接时,第二种方法更上级。在 *nix系统中,有时行为取决于你如何调用程序。因此,对程序名进行硬编码显然是个问题--它永远无法检查这一点。
igsr9ssn2#
我试着把两个世界的最好的:
如果你需要program_name在其他文件中可用,你可以这样声明它:
我声明“char const *”是因为我希望它是一个指向const数据的指针。我不确定我做对了这部分。
pbpqsu0x3#
我通常使用
argv[0]
,或者如果可能的话使用basename(argv[0])
。从用户的观点来看,我认为如果他们重命名或硬链接一个可执行文件(或者其他人为他们这样做),那么他们希望来自它的消息以他们正在使用的名称出现,而不是以他们可能知道或不知道的其他名称编译。类似地,如果你将来发现你想用不同的名字和不同的选项编译你的程序,以给予不同的版本,你想在
#define
周围 Package 一个#ifndef
,并确保它是通过编译器命令行定义的吗?-DPROGRAM_NAME=myprog_demo
,或者你只是想做它,它的工作?例外情况可能是,如果您的使用说明是从手册页或其他文档中摘录的,那么您可能确实希望将程序名硬连接到其中。但是你可能也不会使用
#define
。但是,实现不需要提供
argv[0]
,因此为了获得最佳可移植性,也要处理这种情况。同样,如果您的系统不提供它,那么用户实际上也不会在任何类型的终端上看到消息。顺便说一下:
hi3rlvi24#
第二种方法也可以给予你像
/usr/bin/myprog
这样的字符串,如果你这样执行的话; basename应该给予可执行文件的名称(您可以将其视为程序的名称)。除非它是符号链接的(在这种情况下,你有链接的名称。。其可用于在程序行为中进行某种选择)。第一种方法将程序名“固定”为程序员想要的,不管用户如何重命名可执行文件或符号链接(甚至是硬链接)
1wnzp6jl5#
它并不能确切地回答你关于编程最佳实践的问题,但我认为你也应该记住什么对用户最好。我个人更喜欢使用
argv[0]
引用自己的程序,即。我调用的命令,而不是编码器在程序中硬编码的随机名称。以下是一些硬编码名称令人讨厌或至少没有帮助的例子:$PATH
的不同目录中有多个具有相同基本名称的可执行文件我唯一喜欢硬编码程序名的情况是当我使用GUI应用程序时。我不希望看到“~/foo/bar.pl“作为窗口标题。
6rqinv9w6#
当您手头没有
argv
时,前者上级后者。vtwuwzda7#
取决于
argv
是否在作用域中...hzbexzde8#
全局变量在正确使用时是很好的。可能比
#define
更好,因为至少在调试时可以轻松地检查它们。basename
,然而,引起了我的一些怀疑。