将chars添加到现有的chars / char指针数组中?

时间:2022-07-31 21:16:47

Currently I am reading in a line of strings and parsing it. I'm using the following variables to do so: char **parsed and char *parsed_arguments[64]. Here is the code I use to parse it:

目前我正在阅读一系列字符串并解析它。我使用以下变量来执行此操作:char ** parsed和char * parsed_arguments [64]。这是我用来解析它的代码:

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

That part is fine and dandy, but my problem arises when I try to add to parsed_arguments. What I'm trying to accomplish is reading text from a file, placing it in char buffer[], tokenizing it, and adding it to parsed_arguments so I can pass those arguments to a program using execvp. So far I am able to read text and place it into my buffer and I've even tried tokenizing it, but the last part just confuses me. Here's more code detailing what I'm working on:

那部分很好,花花公子,但是当我尝试添加到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);

1 个解决方案

#1


0  

I think you might be overthinking this problem. Based on the parsing code at the top of your question, you have already solved the problem.

我想你可能会过度思考这个问题。根据问题顶部的解析代码,您已经解决了问题。

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);

Before I describe the caveats that I mentioned (that I know of), I'll quickly explain why this should work: strtok returns the pointer of the last token found in its first argument. This pointer is then written in this variable: *parsed++ (which is an expression that evaluates into an l-value). This dereferences the address pointed to by parsed(which is an element of parsed_arguments). Finally, the post-fix ++ operator simply makes parsed point to the next element of parsed_arguments after the full expression is evaluated.

在我描述我提到的警告(我知道)之前,我会快速解释为什么这应该起作用:strtok返回在其第一个参数中找到的最后一个标记的指针。然后将此指针写入此变量:* parsed ++(这是一个计算结果为l值的表达式)。这解析了解析所指向的地址(这是parsed_arguments的一个元素)。最后,post-fix ++运算符只需在解析完整表达式后使解析指向parsed_arguments的下一个元素。

The important thing to note, is parsed points to the same block of memory occupied by parsed_arguments. By setting parsed = parsed_arguments, *parsed = token is equivalent to parsed_arguments[some_index] = token.

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

You could express your code (not quite as elegantly) without pointer arithmetic as such:

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

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

I hope this is the answer you were looking for, or at least helps point you in the right direction, based on the actual code provided (since a lot is missing, for obvious reasons), and there is a parsed_buf, buf that seem to mimic parsed and parsed_arguments, but those also exist in the code, I am not 100% sure if I completely understand what you are trying to do.

我希望这是你正在寻找的答案,或者至少有助于指出你正确的方向,基于提供的实际代码(由于显而易见的原因,很多东西都缺失了),并且有一个parsed_buf,buf似乎模仿解析和parsed_arguments,但那些也存在于代码中,如果我完全理解你想要做什么,我不是百分之百确定。

Caveats

execvp(...)'s documentation states that by convention, the first element of the arguments should be the file name (I see that you already know this), but nonetheless, make sure the program name is the first element--either have your file's content have the program name first, or just start from the second element.

execvp(...)的文件指出,按照惯例,自变量的第一要素应该是文件名(我看你已经知道这一点),但尽管如此,确保程序的名称是第一要素 - 无论是有你的文件的内容先有程序的名称,或从第二元件刚开始。

execvp(...) also states that the last argument should be a NULL pointer. You can ensure this by a call to memset(parsed_arguments, 0, sizeof(parsed_arguments)); and ensuring the file never specifies more than 64 arguments.

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

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

Lastly, (possibly nit-picking), while (pointer) works on the premise that NULL == 0 (in most cases, it is (void *) 0 AFAIK), I don't know how important it is to you, but if you ever run into an implementation where NULL is not defined as 0, it might cause some issues. So, it would be safer to write while ((*parsed++ = strtok(NULL, SEPARATORS)) != NULL). My two cents anyway.

最后,(可能是挑选),而(指针)工作的前提是NULL == 0(在大多数情况下,它是(void *)0 AFAIK),我不知道它对你有多重要,但是如果您遇到NULL未定义为0的实现,则可能会导致一些问题。因此,写while((* * parsed ++ = strtok(NULL,SEPARATORS))!= NULL)会更安全。反正我的两分钱。

#1


0  

I think you might be overthinking this problem. Based on the parsing code at the top of your question, you have already solved the problem.

我想你可能会过度思考这个问题。根据问题顶部的解析代码,您已经解决了问题。

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);

Before I describe the caveats that I mentioned (that I know of), I'll quickly explain why this should work: strtok returns the pointer of the last token found in its first argument. This pointer is then written in this variable: *parsed++ (which is an expression that evaluates into an l-value). This dereferences the address pointed to by parsed(which is an element of parsed_arguments). Finally, the post-fix ++ operator simply makes parsed point to the next element of parsed_arguments after the full expression is evaluated.

在我描述我提到的警告(我知道)之前,我会快速解释为什么这应该起作用:strtok返回在其第一个参数中找到的最后一个标记的指针。然后将此指针写入此变量:* parsed ++(这是一个计算结果为l值的表达式)。这解析了解析所指向的地址(这是parsed_arguments的一个元素)。最后,post-fix ++运算符只需在解析完整表达式后使解析指向parsed_arguments的下一个元素。

The important thing to note, is parsed points to the same block of memory occupied by parsed_arguments. By setting parsed = parsed_arguments, *parsed = token is equivalent to parsed_arguments[some_index] = token.

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

You could express your code (not quite as elegantly) without pointer arithmetic as such:

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

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

I hope this is the answer you were looking for, or at least helps point you in the right direction, based on the actual code provided (since a lot is missing, for obvious reasons), and there is a parsed_buf, buf that seem to mimic parsed and parsed_arguments, but those also exist in the code, I am not 100% sure if I completely understand what you are trying to do.

我希望这是你正在寻找的答案,或者至少有助于指出你正确的方向,基于提供的实际代码(由于显而易见的原因,很多东西都缺失了),并且有一个parsed_buf,buf似乎模仿解析和parsed_arguments,但那些也存在于代码中,如果我完全理解你想要做什么,我不是百分之百确定。

Caveats

execvp(...)'s documentation states that by convention, the first element of the arguments should be the file name (I see that you already know this), but nonetheless, make sure the program name is the first element--either have your file's content have the program name first, or just start from the second element.

execvp(...)的文件指出,按照惯例,自变量的第一要素应该是文件名(我看你已经知道这一点),但尽管如此,确保程序的名称是第一要素 - 无论是有你的文件的内容先有程序的名称,或从第二元件刚开始。

execvp(...) also states that the last argument should be a NULL pointer. You can ensure this by a call to memset(parsed_arguments, 0, sizeof(parsed_arguments)); and ensuring the file never specifies more than 64 arguments.

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

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

Lastly, (possibly nit-picking), while (pointer) works on the premise that NULL == 0 (in most cases, it is (void *) 0 AFAIK), I don't know how important it is to you, but if you ever run into an implementation where NULL is not defined as 0, it might cause some issues. So, it would be safer to write while ((*parsed++ = strtok(NULL, SEPARATORS)) != NULL). My two cents anyway.

最后,(可能是挑选),而(指针)工作的前提是NULL == 0(在大多数情况下,它是(void *)0 AFAIK),我不知道它对你有多重要,但是如果您遇到NULL未定义为0的实现,则可能会导致一些问题。因此,写while((* * parsed ++ = strtok(NULL,SEPARATORS))!= NULL)会更安全。反正我的两分钱。