在C中将const char参数传递给static char * argv []的语法

时间:2015-04-01 06:46:03

标签: c arrays pointers exec

好的,我正在尝试构建一个守护程序(用于Debian机器),它将接收它接收的命令行参数(通过cron)并将它们传递给不同的脚本文件。

守护程序的main()

 int main(int argc , char *argv[])
 {
        if(argc != 3)
        {
            exit(0);
        }

        daemonize(argv[1], argv[2]);

    return 0;
 }

函数daemonize设置了这个

int daemonize(const char *cmd1, const char *cmd2) {...}

daemonize中令人不安的部分在这里:

if (strcmp(cmd1,"sample_script") == 0)
    {
        static char *argv[] = {"/etc/init.d/sample_script", ["%s",cmd2], NULL };
        execv("/etc/init.d/sample_script",argv);
        exit(127);
    }

在线

  

static char * argv [] = {“/ etc / init.d / sample_script”,(“%s”,cmd2),NULL};

我收到此错误

  

初始化元素不是常量(接近初始化'argv [1]')

显然("%s",cmd2)是错误的。因为使用“开始”工作正常。

那么,如何将cmd2正确地放入*argv[]?或者是我做错了什么?

3 个答案:

答案 0 :(得分:3)

您需要更改

static char *argv[] = {"/etc/init.d/sample_script", ["%s",cmd2], NULL };

const char *argv[] = {"/etc/init.d/sample_script", cmd2, NULL };

您必须删除static关键字。根据章节6.7.9,C11标准,

  

具有static或线程存储持续时间的对象的初始值设定项中的所有表达式   应该是常量表达式或字符串文字。

其中说,在C语言中,static存储持续时间的对象必须使用常量表达式或使用包含常量表达式的聚合初始值设定项进行初始化。

关于常量表达式,来自同一文档的第6.6章

  

可以在转换期间而不是运行时评估常量表达式   因此可以在常数可能的任何地方使用。

因此,在C中,变量(名称),即使声明为const也不是常量表达式


编辑:

要解决最新一期,可以尝试以下

  1. 更改int daemonize(char *cmd1, char *cmd2) {..
  2. 使用char * const argv[] = {"/etc/init.d/sample_script", cmd2, NULL };
  3. 您可以保持其余代码不变。

答案 1 :(得分:2)

execv的函数声明是

int execv(const char *path, char *const argv[]);

对第二个参数的正确解释是{em>" const数组char *" ,它与&#不同34; const char *" 的数组。换句话说,execv保留更改数组指向的字符串内容的权利,但不会更改数组中的任何指针。

这就是说argv数组中的所有字符串都必须在可写内存中。因此,为了在技术上完全正确,代码应该制作所有字符串的可写副本,如此

if (strcmp(cmd1,"sample_script") == 0)
{
    char arg0[] = "/etc/init.d/sample_script";
    char *arg1 = strdup( cmd2 );

    char *argv[] = { arg0, arg1, NULL };
    execv( argv[0], argv );
    exit(127);
}

答案 2 :(得分:0)

您无法使用仅在运行时知道的变量/参数初始化静态。

离开static

char *argv[] = {"/etc/init.d/sample_script", ["%s",cmd2], NULL };