strtok() 在应该有剩余的标记时返回 NULL
strtok() returning NULL when there should be tokens remaining
我正在研究基本的 shell 并使用 strtok 将一行分解为命令,然后将命令分解为参数。但是我 运行 遇到了分词器的问题,没有 return 它应该的所有分词。
例如,我输入字符串ls -l; cat "foo.txt
。分词器应该 return 命令 ls -l
和 cat "foo.txt"
。然后这些命令应该被分成参数 ls
、-l
、cat
和 "foo.txt"
。但是,我得到以下输出。
prompt>ls -l; cat "foo"
Command: ls -l
Number of tokens in command: 2
Token : ls
Token : (null)
Number of tokens in command: 0
我的相关代码如下:
char *commands = strtok(line, ";");
int count = 0;
//get # of commands on line
while(commands != NULL){
count++;
//printf("Command : %s\n", commands);
commands = strtok(NULL, ";");
}
commands = strtok(line, ";");
char *command[count];
//build array of commands
for(int i = 0; i < count; i++){
if(commands != NULL){
command[i] = commands;
printf("Command: %s\n", command[i]);
}
commands = strtok(NULL, ";");
}
//Fork Loop
for(int i = 0; i < count; i++){
//printf("Command: %s\n", command[i]);
char *arglist = strtok(command[i], " ");
int arglistc = 0;
//Count number of args in command
while(arglist != NULL){
arglistc++;
arglist = strtok(NULL, " ");
}
printf("Number of tokens in command: %d\n", arglistc);
char *args[arglistc];
arglist = strtok(command[i], " ");
//Build array of args
for(int j = 0; j < arglistc; j++){
args[i] = arglist;
printf("Arglist value : %s\n", arglist);
printf("Token : %s\n", args[i]);
arglist = strtok(NULL, " ");
}
我不确定自己做错了什么,因为我查找了如何使用 strtok 来填充数组,并且我正在按照解决方案的说明进行操作。
问题
strtok
修改您标记化的字符串,用 0
替换它找到的分隔符。结果是许多字符串存储在原始数组中,用于您的字符串。
解决方案 1:不修改数组
strchr
会找到第一个出现的字符,我们可以用它来统计分词的个数。 只是不要在后面的字符是定界符的循环中增加计数。 然后当您想遍历实际标记时,您可以再次使用它(或 strtok
)。
如果您想允许多个分隔符选项,您也可以使用 strpbrk
。
方案二:遍历数组中嵌入的字符串
在 command[i]
处开始 "Token:"
循环,然后移动到 strtok(arglist + strlen(arglist) + 1, " ")
每一步。
否则
这是C,当然还有其他方案。
我正在研究基本的 shell 并使用 strtok 将一行分解为命令,然后将命令分解为参数。但是我 运行 遇到了分词器的问题,没有 return 它应该的所有分词。
例如,我输入字符串ls -l; cat "foo.txt
。分词器应该 return 命令 ls -l
和 cat "foo.txt"
。然后这些命令应该被分成参数 ls
、-l
、cat
和 "foo.txt"
。但是,我得到以下输出。
prompt>ls -l; cat "foo"
Command: ls -l
Number of tokens in command: 2
Token : ls
Token : (null)
Number of tokens in command: 0
我的相关代码如下:
char *commands = strtok(line, ";");
int count = 0;
//get # of commands on line
while(commands != NULL){
count++;
//printf("Command : %s\n", commands);
commands = strtok(NULL, ";");
}
commands = strtok(line, ";");
char *command[count];
//build array of commands
for(int i = 0; i < count; i++){
if(commands != NULL){
command[i] = commands;
printf("Command: %s\n", command[i]);
}
commands = strtok(NULL, ";");
}
//Fork Loop
for(int i = 0; i < count; i++){
//printf("Command: %s\n", command[i]);
char *arglist = strtok(command[i], " ");
int arglistc = 0;
//Count number of args in command
while(arglist != NULL){
arglistc++;
arglist = strtok(NULL, " ");
}
printf("Number of tokens in command: %d\n", arglistc);
char *args[arglistc];
arglist = strtok(command[i], " ");
//Build array of args
for(int j = 0; j < arglistc; j++){
args[i] = arglist;
printf("Arglist value : %s\n", arglist);
printf("Token : %s\n", args[i]);
arglist = strtok(NULL, " ");
}
我不确定自己做错了什么,因为我查找了如何使用 strtok 来填充数组,并且我正在按照解决方案的说明进行操作。
问题
strtok
修改您标记化的字符串,用 0
替换它找到的分隔符。结果是许多字符串存储在原始数组中,用于您的字符串。
解决方案 1:不修改数组
strchr
会找到第一个出现的字符,我们可以用它来统计分词的个数。 只是不要在后面的字符是定界符的循环中增加计数。 然后当您想遍历实际标记时,您可以再次使用它(或 strtok
)。
如果您想允许多个分隔符选项,您也可以使用 strpbrk
。
方案二:遍历数组中嵌入的字符串
在 command[i]
处开始 "Token:"
循环,然后移动到 strtok(arglist + strlen(arglist) + 1, " ")
每一步。
否则
这是C,当然还有其他方案。