代码之家  ›  专栏  ›  技术社区  ›  Bob Fincheimer

C标记器-它是如何工作的?

  •  3
  • Bob Fincheimer  · 技术社区  · 15 年前

    这是怎么回事?

    我知道怎么用你传过来的:

    • 开始:字符串(例如“项目1、项目2、项目3”)
    • delim:分隔符字符串(例如“,”)
    • sdelim(可选):指向一个字符的指针,该字符将保存令牌的起始delimeter
    • edelim(可选):指向一个字符的指针,该字符将保存令牌的结束符

    代码:

    #include <stdlib.h>
    #include <string.h>
    
    int token(char* start, char* delim, char** tok, char** nextpos, char* sdelim, char* edelim) {
        // Find beginning:
        int len = 0;
        char *scanner;
        int dictionary[8];
        int ptr;
    
        for(ptr = 0; ptr < 8; ptr++) {
            dictionary[ptr] = 0;
        }
    
        for(; *delim; delim++) {
            dictionary[*delim / 32] |= 1 << *delim % 32;
        }
    
        if(sdelim) {
            *sdelim = 0;
        }
    
        for(; *start; start++) {
            if(!(dictionary[*start / 32] & 1 << *start % 32)) {
                break;
            }
            if(sdelim) {
                *sdelim = *start;
            }
        }
    
        if(*start == 0) {
            if(nextpos != NULL) {
                *nextpos = start;
            }
            *tok = NULL;
            return 0;
        }
    
        for(scanner = start; *scanner; scanner++) {
            if(dictionary[*scanner / 32] & 1 << *scanner % 32) {
                break;
            }
            len++;
        }
    
        if(edelim) {
            *edelim = *scanner;
        }
    
        if(nextpos != NULL) {
            *nextpos = scanner;
        }
    
        *tok = (char*)malloc(sizeof(char) * (len + 1));
    
        if(*tok == NULL) {
            return 0;
        }
    
        memcpy(*tok, start, len);
        *(*tok + len) = 0;
    
    
        return len + 1;
    }
    

    dictionary[*delim / 32] |= 1 << *delim % 32;

    dictionary[*start / 32] & 1 << *start % 32

    3 回复  |  直到 15 年前
        1
  •  1
  •   deinst    15 年前

    它们通过在字典中建立一个8x32=256位的表来存储出现的字符。

    dictionary[*delim / 32] |= 1 << *delim % 32;
    

    设置与*delim对应的位

    dictionary[*start / 32] & 1 << *start % 32
    

    检查钻头

        2
  •  4
  •   Brandon Horsley    15 年前

    因为分隔符的每个字符是8位( sizeof(char) ==1字节),限制为256个可能值。

    int dictionary[8] ),每件32种可能性( sizeof(int) 是>=4字节)和32*8=256。

    这形成了一个256位的值矩阵。然后为分隔符中的每个字符打开标志( dictionary[*delim / 32] |= 1 << *delim % 32; *delim / 32

    如果分隔符中存在相应的ASCII字符,则所有这些操作都会将256位矩阵的某些位标记为true。

    然后,确定一个字符是否在分隔符中只是在256位矩阵中查找( dictionary[*start / 32] & 1 << *start % 32 )

        3
  •  0
  •   ChaosPandion    15 年前

    好的,如果我们把字符串 "," delimiter 然后 dictionary[*delim / 32] |= 1 << *delim % 32 dictionary[1] = 4096 . 表达式 dictionary[*start / 32] & 1 << *start % 32

    让我困惑的是他们为什么不直接使用 char 比较。