繁体   English   中英

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

[英]How to cast char* to char *const* in C

我正在尝试使用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;
                        ^

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

帮助将不胜感激。

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

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

char * const a[] = { FileNameOfProgram, arg, NULL };

脚注

1除非使用字符串文字来初始化数组,但此处并非如此。

您正在尝试初始化数组。 而不是这样做

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

做这个:

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

删除命令名和一些第一个参数后,执行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下载此程序的完整版本

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM