strtok() 在应该有剩余的标记时返回 NULL

strtok() returning NULL when there should be tokens remaining

我正在研究基本的 shell 并使用 strtok 将一行分解为命令,然后将命令分解为参数。但是我 运行 遇到了分词器的问题,没有 return 它应该的所有分词。

例如,我输入字符串ls -l; cat "foo.txt。分词器应该 return 命令 ls -lcat "foo.txt"。然后这些命令应该被分成参数 ls-lcat"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,当然还有其他方案。