【问题标题】:Add chars to existing array of chars/ char pointers?将字符添加到现有的字符/字符指针数组?
【发布时间】:2013-04-28 01:18:31
【问题描述】:

目前我正在读取一行字符串并对其进行解析。我正在使用以下变量来执行此操作:char **parsedchar *parsed_arguments[64]。这是我用来解析它的代码:

char newcommand []
parsed =  parsed_arguments;
*parsed++ = strtok(newcommand,SEPARATORS);   // tokenize input
while ((*parsed++ = strtok(NULL,SEPARATORS)))

那部分很好而且很花哨,但是当我尝试添加到 parsed_arguments 时出现了我的问题。我想要完成的是从文件中读取文本,将其放入char buffer[],对其进行标记,并将其添加到parsed_arguments,这样我就可以使用execvp 将这些参数传递给程序。到目前为止,我能够阅读文本并将其放入我的缓冲区中,我什至尝试过对其进行标记,但最后一部分让我感到困惑。以下是详细说明我正在处理的代码的更多代码:

if(file_In)
  {
    //strcpy(input_File_Name,parsed_arguments[input_Index]);

    switch(pid =fork())
      {
      case -1:
        printf("fork error, aborting\n");
        abort();
      case 0:
        parsed_arguments[input_Index-1] = NULL; 
        input_File = freopen(parsed_arguments[input_Index],"r",stdin);
        fgets(buffer, 1023, input_File);

        buf =  parsed_buf;
        *buf++ = strtok(buffer,SEPARATORS);   // tokenize input
        while ((*buf++ = strtok(NULL,SEPARATORS)))

        //strcat(parsed, buf); // invalid

        printf("The buffer holds: %s\n", buffer);
        execvp(parsed_arguments[0],parsed_arguments);

        break;
      default:
        waitpid(pid,NULL,WUNTRACED);

【问题讨论】:

    标签: c file-io char execvp


    【解决方案1】:

    我认为你可能想多了这个问题。根据您问题顶部的解析代码,您已经解决了问题。

    parsed =  parsed_arguments; 
    /* parsed now points to the first element parsed_arguments */
    *parsed++ = strtok(newcommand,SEPARATORS);   // tokenize input
    while ((*parsed++ = strtok(NULL,SEPARATORS)))
        ; /* habit of mine */
    /* At this point, parsed_arguments should be now populated with each
       token from newcommand by strtok
       Minus a few caveats, the following call should be valid */
    execvp(parsed_arguments[0], parsed_arguments);
    

    在描述我提到的(我知道的)警告之前,我将快速解释为什么这应该有效: strtok 返回在其第一个参数中找到的最后一个标记的指针。然后将此指针写入此变量中:*parsed++(这是一个计算结果为左值的表达式)。这将取消引用parsed(它是parsed_arguments 的一个元素)指向的地址。最后,后缀++ 运算符只是让parsed 指向parsed_arguments 的下一个元素完整表达式被求值之后。

    需要注意的重要一点是,parsed 指向parsed_arguments 占用的同一块内存。通过设置parsed = parsed_arguments*parsed = token等价于parsed_arguments[some_index] = token

    你可以在没有指针算法的情况下表达你的代码(不是很优雅):

    int argc = 0;
    /* declarations, etc *SNIP* */
    parsed_arguments[argc] = strtok(newcommand, delim);
    while (parsed_arguments[argc++]) {
        parsed_arguments[argc] = strtok(NULL, delim);
    }
    

    我希望这是您正在寻找的答案,或者至少可以根据所提供的实际代码帮助您指出正确的方向(由于明显原因缺少很多内容),并且有一个parsed_buf , buf 似乎模仿了 parsedparsed_arguments,但它们也存在于代码中,我不能 100% 确定我是否完全理解您要做什么。

    注意事项

    execvp(...) 的文档指出,按照惯例,参数的第一个元素应该是文件名(我看到您已经知道这一点),但是,请确保程序名称是第一个元素——或者让您的文件内容首先具有程序名称,或者仅从第二个元素开始。

    execvp(...) 还声明最后一个参数应该是一个 NULL 指针。您可以通过调用memset(parsed_arguments, 0, sizeof(parsed_arguments)); 来确保这一点,并确保文件从不指定超过 64 个参数。

    http://linux.die.net/man/3/execvp

    最后,(可能是吹毛求疵)while (pointer)NULL == 0 的前提下工作(在大多数情况下,它是(void *) 0 AFAIK),我不知道它对你有多重要,但如果您曾经遇到过 NULL 未定义为 0 的实现,这可能会导致一些问题。所以,写while ((*parsed++ = strtok(NULL, SEPARATORS)) != NULL) 会更安全。反正我的两分钱。

    【讨论】:

    • 感谢您的回答。我要做的是将文件的内容作为参数传递给程序。即./programname < filename。知道怎么做吗?我相信它类似于使用批处理文件。
    • ./programname < filename (无论如何,在 Bash 和 cmd 中)只是将程序的标准输入重定向到文件(就像 ./programname > filename 将标准输出重定向到文件一样)这是你想要做的吗?我以为你的意思是file=some arg list,然后是./programname some arg list。据我所知,如果你想要文件重定向,在调用 fork() 之后(如果成功),你只需要打开文件,将文件描述符复制到 STDIN_FILENO(有效替换 STDIN_FILENO)然后调用execvp(...)@ 987654322@linux.die.net/man/3/open
    猜你喜欢
    • 2020-01-12
    • 1970-01-01
    • 2020-08-09
    • 2020-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-16
    • 2015-08-12
    相关资源
    最近更新 更多