目前我正在读取一行字符串并对其进行解析。为此,我使用以下变量:char **parsed
和 char *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);
最佳答案
我认为您可能对这个问题想得太多了。根据问题顶部的解析代码,您已经解决了问题。
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
的下一个元素 after 完整的表达式被评估。
需要注意的重要一点是,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
似乎模仿了 parsed
和 parsed_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)
会更安全。无论如何我的两分钱。
关于c - 将字符添加到现有的字符/字符指针数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16258567/