结构数组只采用 C 中的最后一个值
Array of structs only takes last value in C
我正在尝试制作一个简单的命令行界面,但我遇到了解析命令的问题:
process_t 是一个结构,包含要存储在变量 argv 中的参数的命令路径。
int parse_cmd(char* tokens[], process_t* commands) {
assert(tokens!=NULL);
assert(commands!=NULL);
int position = 0;
int commandNumber = 0;
for(int i=0; tokens[i] != NULL; i++){
if(is_reserved(tokens[i]) == 0 && tokens[i+1] != NULL) continue;
int end = is_reserved(tokens[i]) == 0 ? i+1 : i;
int argc = position;
int count = 0;
process_t newProcess;
char* argv[MAX_CMD_SIZE] = {NULL};
for(argc; argc < end; argc++) {
argv[count] = tokens[argc];
count = count + 1;
}
newProcess.path = tokens[position];
newProcess.argv = argv;
position = i + 1;
commands[commandNumber] = newProcess;
commandNumber = commandNumber + 1;
}
}
int main(int argc, char* argv[]) {
char path[MAX_LINE_SIZE];
char line[MAX_LINE_SIZE];
char* cmdline[MAX_CMD_SIZE];
process_t cmds[MAX_CMD_SIZE];
getcwd(path, MAX_LINE_SIZE);
while (1) {
printf("mini@shell:%s$ ", path);
scanf("%[^\n]%*c", line);
trim(line);
clean(line);
tokenize(line, cmdline);
parse_cmd(cmdline, cmds);
toString(cmds);
break;.
}
return -1;
}
输入:ls -l ; grep ^a
为什么数组只包含最后一次迭代的 argv 值?
输出:
路径:ls => argv = {grep, ^a, (null)}
路径:grep => argv = {grep, ^a, (null)}
您正在尝试使用块局部数组 argv
,它会为每个命令重新创建,更糟糕的是,在 parse_cmd
返回后甚至不再存在。必须使用具有足够生命周期的数组对象;你可以通过改变
来做到这一点
char* argv[MAX_CMD_SIZE] = {NULL};
到
char **argv = calloc(end-position+1, sizeof *argv);
请注意,您必须在不再需要时 free
此对象。
另请注意,您忘记从 parse_cmd
到 return commandNumber;
;否则,您无法知道找到了多少命令。
我还找到了一种方法,甚至不需要复制我声明的本地数组,只需更改包含保留字符的索引值即可。
所以令牌将是这样的:{« ls », « -l », NULL, « grep », « ^a », NULL}
int parse_cmd(char* tokens[], process_t* commands) {
assert(tokens!=NULL);
assert(commands!=NULL);
int position = 0;
int commandNumber = 0;
for(int i=0; tokens[i] != NULL; i++){
if(is_reserved(tokens[i]) == 0 && tokens[i+1] != NULL) continue;
int end = is_reserved(tokens[i]) == 0 ? i+1 : i;
commands[commandNumber].path = tokens[position];
commands[commandNumber].argv = &tokens[position];
commands[commandNumber].next = &commands[commandNumber]+1;
tokens[end] = NULL;
commandNumber = commandNumber + 1;
position = i + 1;
}
return 0;
}
我正在尝试制作一个简单的命令行界面,但我遇到了解析命令的问题:
process_t 是一个结构,包含要存储在变量 argv 中的参数的命令路径。
int parse_cmd(char* tokens[], process_t* commands) {
assert(tokens!=NULL);
assert(commands!=NULL);
int position = 0;
int commandNumber = 0;
for(int i=0; tokens[i] != NULL; i++){
if(is_reserved(tokens[i]) == 0 && tokens[i+1] != NULL) continue;
int end = is_reserved(tokens[i]) == 0 ? i+1 : i;
int argc = position;
int count = 0;
process_t newProcess;
char* argv[MAX_CMD_SIZE] = {NULL};
for(argc; argc < end; argc++) {
argv[count] = tokens[argc];
count = count + 1;
}
newProcess.path = tokens[position];
newProcess.argv = argv;
position = i + 1;
commands[commandNumber] = newProcess;
commandNumber = commandNumber + 1;
}
}
int main(int argc, char* argv[]) {
char path[MAX_LINE_SIZE];
char line[MAX_LINE_SIZE];
char* cmdline[MAX_CMD_SIZE];
process_t cmds[MAX_CMD_SIZE];
getcwd(path, MAX_LINE_SIZE);
while (1) {
printf("mini@shell:%s$ ", path);
scanf("%[^\n]%*c", line);
trim(line);
clean(line);
tokenize(line, cmdline);
parse_cmd(cmdline, cmds);
toString(cmds);
break;.
}
return -1;
}
输入:ls -l ; grep ^a
为什么数组只包含最后一次迭代的 argv 值?
输出:
路径:ls => argv = {grep, ^a, (null)} 路径:grep => argv = {grep, ^a, (null)}
您正在尝试使用块局部数组 argv
,它会为每个命令重新创建,更糟糕的是,在 parse_cmd
返回后甚至不再存在。必须使用具有足够生命周期的数组对象;你可以通过改变
char* argv[MAX_CMD_SIZE] = {NULL};
到
char **argv = calloc(end-position+1, sizeof *argv);
请注意,您必须在不再需要时 free
此对象。
另请注意,您忘记从 parse_cmd
到 return commandNumber;
;否则,您无法知道找到了多少命令。
我还找到了一种方法,甚至不需要复制我声明的本地数组,只需更改包含保留字符的索引值即可。
所以令牌将是这样的:{« ls », « -l », NULL, « grep », « ^a », NULL}
int parse_cmd(char* tokens[], process_t* commands) {
assert(tokens!=NULL);
assert(commands!=NULL);
int position = 0;
int commandNumber = 0;
for(int i=0; tokens[i] != NULL; i++){
if(is_reserved(tokens[i]) == 0 && tokens[i+1] != NULL) continue;
int end = is_reserved(tokens[i]) == 0 ? i+1 : i;
commands[commandNumber].path = tokens[position];
commands[commandNumber].argv = &tokens[position];
commands[commandNumber].next = &commands[commandNumber]+1;
tokens[end] = NULL;
commandNumber = commandNumber + 1;
position = i + 1;
}
return 0;
}