我的代码应该将字符数组解析为 ***char,以便它首先用“|”将其分割char 然后由空格、换行符等转换成单词。输入/输出示例:
I = ls -l | sort | unique
O=
*cmds[1] = {"ls", "-l", NULL};
*cmds[2] = {"sort", NULL};
*cmds[3] = {"unique", NULL};
上面是指向 char 数组的指针,因此按单词分割,下面是 ***char 以及指向上面指针的指针
char **cmds[] = {1, 2, 3, NULL};
现在,我没有看到我的错误(可能是因为我对 C 不太熟练),但是当我从 parsePipe() 内部调用 parse(..) 函数时,程序给出了段错误。有人可以帮忙吗?
void parse(char *line, char **argv)
{
while (*line != '\0') {
while (*line == ' ' || *line == '\t' || *line == '\n')
*line++ = '\0';
*argv++ = line;
while (*line != '\0' && *line != ' ' && *line != '\t' && *line != '\n'){
line++;
}
}
*argv = '\0';
}
void parsePipe(char *line, char ***cmds)
{
char *cmd = strtok(line, "|");
int word_counter = 0;
while (cmd != NULL)
{
printf("Printing word -> %s\n", cmd);
word_counter++;
parse(cmd, *cmds++);
cmd = strtok(NULL, "|");
}
printf("This string contains %d words separated with |\n",word_counter);
}
void main(void)
{
char line[1024];
char **cmds[64];
while (1) {
printf("lsh -> ");
gets(line);
printf("\n");
parsePipe(line, cmds);
}
}
最佳答案
[评论太长]
这一行
*argv++ = line; /* with char ** argv */
指的是无效内存,因为代码中的*argv[n]
(带有字符**argv[64]
)没有任何内容。
您使用的命名并不会让生活变得更轻松。
尝试以下命名:
void parse(char *line, char **cmd)
{
while (*line != '\0') {
while (*line == ' ' || *line == '\t' || *line == '\n')
*line++ = '\0';
*cmd++ = line;
while (*line != '\0' && *line != ' ' && *line != '\t' && *line != '\n'){
line++;
}
}
*argv = '\0';
}
void parsePipe(char *line, char ***cmdline)
{
char *cmd = strtok(line, "|");
int word_counter = 0;
while (cmd != NULL)
{
printf("Printing word -> %s\n", cmd);
word_counter++;
parse(cmd, *cmdline++);
cmd = strtok(NULL, "|");
}
printf("This string contains %d words separated with |\n",word_counter);
}
void main(void)
{
char line[1024];
char **cmdline[64];
while (1) {
printf("lsh -> ");
gets(line);
printf("\n");
parsePipe(line, cmdline);
}
}
因为 cmd
所使用的内存都没有被分配。
所以
*cmd++ = line;
失败,因为cmd
无处指向,但被取消引用,代码尝试写入它所指向的位置,但无处可去,即无效内存。
可以通过将 char***
传递给 parse(char *** pcmd)
并计算找到的标记来解决此问题
size_t nlines = 0;
...
++nlines.
并且正在做
*pcmd = realloc(*pcmd, nlines + 1); /* Allocate one more as needed to later find the end of the array. */
(*pcmd)[nlines -1] = line;
(*pcmd)[nlines] = NULL; /* Initialise the stopper, marking the end of the array. */
对于找到的每个 token 。
显然你需要这样调用它:
parse(cmd, cmdline++);
要完成所有这些工作,初始数组需要正确初始化(无论如何你都应该这样做):
char **cmdline[64] = {0};
关于c - 将行解析为 ***char 时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27091723/