c - 如何将标记化行与 str "exit"进行比较?

标签 c

我不知道如何将该行与“退出”一词进行比较,以便当键盘输入退出时程序将退出。 #定义 MAX_LINE 4096 #定义 MAX_WORDS MAX_LINE/2

int main()
{
        char line[MAX_LINE], *words[MAX_WORDS], message[MAX_LINE];
        int stop=0,nwords=0;

        while(1)
        {
                printf("OSP CLI $ ");
        fgets(line,MAX_LINE,stdin);

        if(strcmp(line,"exit")==0)
        {
            exit(0);
        }   
void tokenize(char *line, char **words, int *nwords)
{
    *nwords=1;
    for(words[0]=strtok(line," \t\n");
       (*nwords<MAX_WORDS)&&(words[*nwords]=strtok(NULL, " \t\n"));
        *nwords=*nwords+1
    ); /* empty body */
    return;
}

代码是正确的,但我不知道它的作用。因此 for(words[0]=strtok(line,"\t\n"); 读取该行中的第一个单词。“line”是用户在运行时输入的键盘输入,它只是一个字符串,例如: hello world blah dee doo。但在那之后,下一行带有 nwords<..... 在 for 行之后不明白任何内容。

最佳答案

for (a; b; c) d;

可以翻译成:

a;
while (b) {
   d;
   c;
}

所以:

void tokenize(char *line, char **words, int *nwords)
{
    *nwords=1;
    for(words[0]=strtok(line," \t\n");
       (*nwords<MAX_WORDS)&&(words[*nwords]=strtok(NULL, " \t\n"));
        *nwords=*nwords+1
    ); /* empty body */
    return;
}

可以翻译成(有一些其他改进,例如 int *a; if (a)int *a; if (a != NULL) 相同):

void tokenize(char *line, char **words, int *nwords)
{
    *nwords = 1;
    words[0] = strtok(line, " \t\n");
    while ( 
             *nwords < MAX_WORDS && 
             (words[*nwords] = strtok(NULL, " \t\n")) != NULL
    ) {
        /* empty body */
        *nwords = *nwords + 1;
    }
}

让我们再详细一点:

void tokenize(char *line, char **words, int *nwords)
{
    *nwords = 1;
    words[0] = strtok(line, " \t\n");
    while (*nwords < MAX_WORDS) {
        words[*nwords] = strtok(NULL, " \t\n");
        if (words[*nwords] == NULL) {
            break;
        }
        /* empty body */
        *nwords = *nwords + 1;
    }
}

这个函数很危险,或者可能是更大的函数的一部分(不检查参数是否为空,并且如果行为空则忽略)。

words是一个指针,它是一个 char* 的数组指针。 words的长度指针似乎至少是 MAX_WORDS长的。 nwords是指向 words 返回长度的指针指针。调用者期望此函数填充 words内存和nwords带有字符串标记的内存。假设所有指针都不为 NULL 并且有效,MAX_WORDS > 0strlen(line) != 0或者字符串 line不仅仅包含 " \t\n"我们使用分隔符,以便始终存在第一个标记。

  • 首先是nwords初始化为1 ,并提取第一个 token words[0] = strtok(line, " \t\n");
  • 然后直到 token 数量低于 MAX_WORDS提取下一个 token words[*nwords] = strtok(NULL, " \t\n")
  • 来自 strtok手册 - 从 strtok 返回的值是“如果没有更多 token 则为 NULL”。如果strtok返回 NULL,意味着我们完成了字符串 - 所以我们从函数返回。
  • 如果 token 数量低于 MAX_WORDS我们提取了下一个有效 token ,我们增加计数 *nwords = *nwords + 1;
  • 调用者留下 wordsline 内的指针初始化string,nwords后面的内存使用 token 计数和 line 进行初始化数组被修改为具有终止零 '\0'代替 token 分隔符。

关于c - 如何将标记化行与 str "exit"进行比较?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55627218/

相关文章:

c - 第二个线程上的 PTHREAD_MUTEX_RECURSIVE block

c - 查找客户端使用的端口号

c - 谁免费的 setvbuf 缓冲区?

更改传递的文件名的扩展名

c - 在 C 中表示字符的最佳方式是什么?

c - 为什么导出的由另一个驱动程序修改的常量值未在原始驱动程序中更新

c - Essential C 书中的 Swap() func 无法编译

c - 包含非标准 header 时,YouCompleteMe 不会显示错误

c - 在 RichEdit Winapi 中实现 "tab completion"

c - 为什么 OSX 记录 atoi/atof 不是线程安全的?