`

strtok三段代码分析

 
阅读更多

 

 

unsigned char map[32];
        /*str:原始字符串,ctrl:分割字符串*/
        /* Set bits in delimiter table */
        do {
                map[*ctrl >> 3] |= (1 << (*ctrl & 7));
        } while (*ctrl++);

        while ( (map[*str >> 3] & (1 << (*str & 7))) && *str )
                str++;

 

第一个map是一个对照表。为什么选择了32呢?(可以先看下文)每个下标对应8位,每个char为8bit,有256个字符。32*8=256,刚好等于


第二个do..while构造map表,仿佛如下:

*ctrl>>3,除以8,那么每个下标对应的就有8个目标。比如下标0对应着0~7,下标1对应着8~15

*ctrl & 7,取低3位,进行移位。

这里一个巧的地方就是一个进制的换算。char刚好是8位,而每个数组存放的范围是小于8的倍数,比如上提到的0~7。那么在这个范围内,每个值刚好可以对应一个bit.然后再将这些bit进行一个掩码的组合。


第三个while,是一个比较,对str采取一个统一的处理,首先除8找到下标,然后将对应的字符于map进行一个&,如果str中也有这个字符,则符合条件,进行下一轮。


那么根据这些掩码限制,strtok一些性质可以得到如下:

如果ctrl字符顺序和str顺序即时不符合,也会返回;

最多支持8个ctrl的长度;

 

测试代码一:

int _tmain(int argc, _TCHAR* argv[])
{
		char s[]="1111 2222 333";
        char *d=" ";
        char *p;

        p=strtok(s,d);
        while(p)
        { 
            printf("%s\n",p);
			 p = strtok(NULL,d);
        }

	return 0;	
}

/*
   输出
*/
1111
2222
333
 

测试代码二:

int _tmain(int argc, _TCHAR* argv[])
{
		char s[]="1111ab2222ba333";
        char *d="ab";
        char *p;

        p=strtok(s,d);
        while(p)
        { 
            printf("%s\n",p);
			 p = strtok(NULL,d);
        }

	return 0;	
}

/*
  输出
*/
1111
2222
333

 测试三

int _tmain(int argc, _TCHAR* argv[])
{
		char s[]="1111abcdefghi2222iabcdefgh333";
        char *d="abcdefgh";
        char *p;

        p=strtok(s,d);
        while(p)
        { 
            printf("%s\n",p);
			 p = strtok(NULL,d);
        }

	return 0;	
}

/*
   输出
*/
1111
i2222i
333
结尾,这种内容上的技巧可以经常在库代码中看到。而且现在似乎也只能在库代码中看到,在看完无数的数组遍历诸如代码之后,这些不是非常高深的技巧却经常让人嗟呼不已。计算机性能的发展远远落后人类的需求,并不能依靠硬件性能就开始一浆糊的写代码。 如果你一浆糊了,你的后来人还能说硬件性能如何,不考虑什么什么如何这句话吗?当然我不想扯得多高深,涉及到整个行业的进步上去。但也不是说去忽视计算机的性能。硬件性能的便利,使我们可以写出更人性化的代码,少掉许多奇淫技巧,可以去思考和拓展更多的东西,但是切忌浆糊式的代码出来。多锻炼自己的脑子,才能显得稍微灵光点。反正,我是不想变得和你一样。

 

1
3
分享到:
评论

相关推荐

    c++实现字符串读取

    这段代码的主要功能是以逗号和空格为分隔符,将一个字符串分解成多个子字符串,并打印出这些子字符串。接下来,我们将逐一解析其中的关键部分。 1. **初始化**:定义了一个长度为255的字符数组`buffer`,并赋值了一...

    c++的一些问题

    下面是一段典型的使用 `strtok` 进行字符串分割的例子: ```c #include #include int main() { char str[] = "-This,asamplestring."; char *pch; printf("Splitting string \"%s\" into tokens:\n", str);...

    INI文件操作源码

    1. `[section]`:表示一个配置段,类似数据库中的表,每个section可以包含多个键值对。 2. `key=value`:键值对,key是配置项的名字,value是对应的值。例如,`FontSize=12`表示字体大小为12。 3. 注释:通常以分号`...

    opengl读DEM数据的代码

    总的来说,这段代码实现了从ASCII格式的栅格文件中读取和解析DEM数据,但并未涉及如何利用OpenGL进行可视化。为了在OpenGL中绘制这个地形,你需要进一步的代码来构建顶点数组,设置模型视图矩阵,以及调用OpenGL的...

    字符串相关函数介绍

    运行这段代码,你会看到`strchr`找到字符'!'的位置,`strstr`找到子串'test'的位置,而`strtok`则将字符串按空格、逗号和感叹号进行拆分。 理解并熟练运用这些字符串函数对于编程至关重要,尤其是在处理文本数据、...

    特定字符分割字符串 特定字符分割字符串

    这段代码的作用是解析`m_csInput`成员变量中存储的字符串,它应该是一个包含三个由逗号分隔的整数的字符串。`"%d,%d,%d"`是格式字符串,其中`%d`是转换说明符,表示接下来读取的是十进制整数。`&a`, `&b`, `&c`是...

    基于PHP收货地址智能解析

    2. **地址分隔**:用户输入的地址可能是一段连续的字符串,我们需要使用正则表达式或其他字符串处理函数(如`explode()`、`strtok()`)将其分解为各个组件,如街道、城市、省份、邮政编码等。 3. **地址规范化**:...

    字符串切割

    这段代码会按空格切割字符串,并打印出每一个子字符串。这里我们使用了`const_cast`来转换常量指针,因为`strtok`要求传入的字符串可以被修改。 在实际应用中,如果你需要处理Unicode字符串,可能需要使用`wstring`...

    通讯录C源码

    - 这段代码首先提示用户输入想要执行的操作,然后将输入的命令转换为小写,便于匹配。 - 接下来通过一系列条件语句判断用户的选择,并调用相应的函数执行相应操作。 #### 2. 联系人信息的添加 在 `New(int rewrite)...

    c 网络爬虫

    在爬虫中,URL分析是初始阶段,包括解析和验证URL的有效性。这通常涉及以下几个步骤: - **解析URL结构**:URL由协议(如http或https)、主机名、端口号、路径、查询字符串和片段标识符组成。C语言中可以使用标准...

    gps.gz_GPS_GPS数据_读取GPS

    在IT领域,GPS(全球定位系统)是一种广泛应用于导航、定位和时间同步的重要技术。...`gps.c`文件中的代码可能是实现这一过程的一个实例,通过学习和理解这段代码,我们可以更好地掌握如何在实际项目中运用GPS技术。

    2numbersandmaxofstring.rar_between

    这段代码会找到字符串中的最大数字(假设非数字字符用于分隔数字)。 **C语言编程基础** 在 "avebarasınadkileriyazdir.c" 和 "dizi maksimum sayi.c" 文件中,我们可以预期看到C语言的基本语法,包括变量声明、...

    网易公开课中英字幕合并

    在阅读和理解他人的代码时,要注意理解算法思想,分析代码结构,并且学习如何优化和调试代码。 总之,“网易公开课中英字幕合并”涉及到C语言编程、文件操作、字符串处理、时间格式转换、数据结构和排序算法等多个...

    matlab读取envi影像(亲测可用)

    下面是一段示例代码,展示了如何使用MATLAB读取ENVI标准格式的图像数据: ```matlab % 读取ENVI标准格式图像数据 function [image, p, t, b] = freadenvi(fname) % 输入: % fname - 字符串,给出待读取ENVI图像的...

    pp.rar_it

    这段代码从字符串末尾开始搜索,检查每个字符是否为空格,并确保它前面不是换行符。如果找到符合条件的空格,它将打印出该空格的位置。 总结起来,"pp.rar_it"可能包含了一个关于C语言编程的示例,涉及字符串操作,...

    inux系统分析之进程线程

    ### Linux系统分析之进程与线程 #### 一、进程的概念与组成 进程是操作系统为了管理正在执行的程序而引入的基本单位。一个进程不仅包含了正在执行的程序代码本身,还包括了该程序执行所需的资源,如虚拟处理器、...

    黑马ios基础测试题

    1. 这段代码主要涉及预增操作符和后增操作符的使用。`b`的值首先被设置为`a`的初始值(5)加上`a`自增1后的值,然后`a`再自增1。因此,`b`的值将是`6 + 6 = 12`,而`a`的最终值将是`7`。所以,代码会打印`b=12, a=7`...

    lab4_processCommunication.zip

    在"lab4_processCommunication.zip"这个实验中,我们将深入探讨如何在Linux环境下使用C语言实现多进程间的通信,具体涉及读入进程、处理进程和显示进程三个关键组件。这些进程分别承担着不同的任务:读入进程接收...

    用C对英文单词进行词频统计

    三、C语言实现关键代码段 ```c // 定义二叉树节点 typedef struct Node { char word[50]; int frequency; struct Node* left; struct Node* right; } Node; // 插入单词 Node* insert(Node* root, char* word)...

Global site tag (gtag.js) - Google Analytics