如何在C中将char *转换为char * const *

时间:2019-06-30 20:55:15

标签: c casting char

我正在尝试使用execv()函数。

我试图将参数命令传递到左侧。

 execv(file,arguments);

我正在使用char *来解析我的shell的输入用户输入。

execv的第二个参数采用char * const *。

有没有办法将char * const强制转换为char * const *?

我在下面尝试,

char * arg;
char *const a[] = (char *const)arg;

error: invalid initializer
      char *const a[] = (char *const)arg;
                        ^

但是它不起作用,并给我错误。

将不胜感激。

3 个答案:

答案 0 :(得分:3)

char *const a[] = (char *const)arg;中的错误不是由于转换不正确引起的。这是因为char *const a[]声明了一个数组,并且该数组的初始化程序必须位于大括号 1 { … }中,但是您只指定了一个不带有大括号的初始化程序。

此外,argv的{​​{1}}参数应该是一个指针数组,其中第一个指针指向包含正在执行的程序的文件名的字符串(按惯例,这不是必需的)最后一个是空指针。因此,您对execv的定义应类似于:

a

脚注

1 除非使用字符串文字来初始化数组,但是这里不是这种情况。

答案 1 :(得分:0)

您正在尝试初始化数组。

char * arg;
char *const a[] = (char *const)arg;

执行此操作:

char * arg;
char *const a[] = {(char *const)arg};

答案 2 :(得分:0)

在删除命令名称和一些第一个参数之后,执行execv是很正常的。例如,如果您有类似的代码(最好发布一个完整且可验证的示例),那么假设您正在执行类似的操作(如果您想要一个示例,请查找xargs(1)联机帮助页,您可以找到一条命令,并在处理了选项及其参数之后,想要消除所有选项,并像执行命令行一样执行其余操作,例如,我有一条命令重复执行一条命令,从而延迟了指定的时间,例如:

cont -t 0.1 -- df -k .

我使用<getopts.h>处理cont程序的选项,然后重复执行命令df -k。使用选项可以显示程序的版本,指定超时,详细信息或执行命令的次数。我刚刚写了它,以向您展示如何做(该示例包括fork(2)的使用,execvp(2)和重定向,以捕获命令的输出,以便能够返回到原点(一旦知道)我们收到的行数,程序使用ANSI转义将光标移回开头。)

#include <stdlib.h>
#include <stdio.h>
#include <getopt.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

#define F(_fmt) "%s:%d: " _fmt, __FILE__, __LINE__

#define FLAG_VERBOSE        (1<<0)
#define FLAG_VERSION        (1<<1)
#define FLAG_DELAY          (1<<2)
#define FLAG_NTIMES         (1<<3)

int flags = 0;
useconds_t delay = 1000000;
size_t ntimes;

void doVersion(void)
{
    fprintf(stderr, 
            "cont: v1.0\n"
            "(C) Luis Colorado.  All rights reserved.\n"
            "License: BSD\n");
    exit(EXIT_SUCCESS);
}

ssize_t loop(int argc_unused, char **argv)
{
    int fd[2];
    int res = pipe(fd);

    res = fork();
    if (res < 0) {
            fprintf(stderr,
                    F("fork: ERROR %d: %s\n"),
                    errno,
                    strerror(errno));
            return -1;
    } else if (res == 0) { /* child */
            close(fd[0]); /* not going to use it */
            dup2(fd[1], 1); /* redirect output to pipe */
            close(fd[1]);

            execvp(argv[0], argv);

            fprintf(stderr,
                    F("execv: ERROR %d: %s\n"),
                    errno, strerror(errno));
            return -1;
    } else { /* parent */
            pid_t cld_pid = res;
            close(fd[1]); /* no writing to the pipe */
            FILE *f = fdopen(fd[0], "rt"); /* just reading */
            int c;
            size_t lines = 0;
            while((c = fgetc(f)) != EOF) {
                    if (c == '\n') lines++;
                    putc(c, stdout);
            }
            wait(NULL);
            return lines;
    }

} /* loop */

int main(int argc, char **argv)
{
    int opt;
    float t;

    while ((opt = getopt(argc, argv, "t:Vvn:")) >= 0) {
            switch(opt) {
            case 't': flags |= FLAG_DELAY;
                              t = atof(optarg);
                              break;
            case 'V': flags |= FLAG_VERSION;
                              break;
            case 'v': flags |= FLAG_VERBOSE;
                              break;
            case 'n': flags |= FLAG_NTIMES;
                              ntimes = atoi(optarg);
                              break;
            /* ... */
            }
    }

    if (flags & FLAG_VERSION)
            doVersion();

    /* the next pair of sentences is like `shift optind' in the shell. */
    /* trick, don't move the parameters, just move the pointer */
    argc -= optind; /* adjust the number of parameters. */
    argv += optind; /* advance the pointer to the proper place */

    /* NOW, argc && argv are identical to the original ones, but lacking the
     * first `optind' argument strings.  As the original string array ended
     * in a NULL, there's no need to construct it from allocating memory.
     * Anyway, we're not going to use after it's consumed in main().  */

    if (flags & FLAG_VERBOSE) {
            char *sep = "About to execute: ";
            int i;
            for (i = 0; i < argc; i++) {
                    fprintf(stderr, "%s%s", sep, argv[i]);
                    sep = " ";
            }
            fprintf(stderr, "\n");
    }

    if (flags & FLAG_DELAY) {
            delay = t * 1.0E6;
    }

    size_t total_lines = 0;
    ssize_t n = 0;
    while(!(flags & FLAG_NTIMES) || ntimes--) {

            /* move up as many lines as input from subcommand */
            if (n) printf("\r\033[%ldA@\b", n);

            n = loop(argc, argv);

            if (n < 0) {
                    /* we have already written the error */
                    exit(EXIT_FAILURE);
            }

            usleep(delay);

            total_lines += n;
    }
    if (flags & FLAG_VERBOSE) {
            fprintf(stderr,
                    F("Total lines: %lu\n"),
                    total_lines);
    }
    exit(EXIT_SUCCESS);
}

您可以从Github下载该程序的完整版本