在 Windows 内核开发中,字符串并非像 C 中使用的是一个 \0 结尾的字符数组,取而代之的是一个结构体,该结构体储存了指向字符的指针和字符的长度。因为没有了 \0,很多 C 语言库函数也无法使用了,但不用担心,Windows 提供了很多操作这种字符串的函数。见如下示例:

继续阅读

所谓全排列就是将一个数据组合拆开重新排列,比如 abc,可重新排序为 acb、bac、bca、cab、cba,通过算法上实现一般就是递归或一个while循环来实现。最近复习算法方面的内容接触到的新的算法,记录一下思路。

继续阅读

QString 是 Qt 内部的一种字符串数据类型,QString 支持多字节编码(unicode)的一个字符串类。在程序和网络之间传输数据时,其他的程序和网络另一端的程序是不能识别他这种数据类型的。所以要想将 QString 类型的数据保存到文件或发送到网络,需要转换成 QByteArray 类型才可以。继续阅读

boost filesystem::path 是对文件目录路径做处理的一个小的类,他把我们平时处理文件路径的繁琐功能简化到不能再简化,比如我们想获取一个路径中的文件名,只需要调用 object.filename().string() 就可以了,如果是C语言或者C++中提供的系统库中,我们是找不到这么方便的方法的。更多的一些功能见下面代码。你也可以查看 boost 帮助文档,查找更多的功能。

继续阅读

你在使用编辑器写代码的时候是否思考过这个问题:如果少写了一个大括号或中括号,编辑器就会提示错误,这种做法是怎么做到的呢?

其实这个检测就可以通过栈模型来实现,括号的数量总是匹配出现的,并且都是与最近的一个匹配。我们可以编写代码来实现这个检测的功能。具体实现思路如下:

从第一个字符开始扫描, 当遇见普通字符时忽略,
当遇见左符号时压入栈中
当遇见右符号时从栈中弹出栈顶符号,并进行匹配.
匹配成功:继续读入下一个字符
匹配失败:立即停止,并报错
结束.
------成功: 所有字符扫描完毕,且栈为空
------失败:匹配失败或所有字符扫描完毕但栈非空

【实现代码】

以下代码需要用到栈模型链式存储的 LinkStack.h 和 LinkStack.c 头文件

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "LinkStack.h"

/***************** 算法思路 *****************
从第一个字符开始扫描, 当遇见普通字符时忽略,
当遇见左符号时压入栈中
当遇见右符号时从栈中弹出栈顶符号,并进行匹配.
匹配成功:继续读入下一个字符
匹配失败:立即停止,并报错
结束.
------成功: 所有字符扫描完毕,且栈为空
------失败:匹配失败或所有字符扫描完毕但栈非空*/

int match(char left, char right)
{
	int ret = 0;
	switch (left)
	{
	case '<':	//左尖括号
		ret = (right == '>');
		break;
	case '(':	//左小括号
		ret = (right == ')');
		break;
	case '[':	//左中括号
		ret = (right == ']');
		break;
	case '{':	//左大括号
		ret = (right == '}');
		break;
	case '\'':	//左单引号
		ret = (right == '\'');
		break;
	case '\"':	//左双引号
		ret = (right == '\"');
		break;
	default:
		ret = 0;
		break;
	}

	//匹配成功返回1,不成功返回0
	return ret;
}

int isRight(char right)
{
	int ret = 0;
	switch (right)
	{
	case '>':	//右尖括号
	case ')':	//右小括号
	case ']':	//右中括号
	case '}':	//右大括号
	case '\'':	//右单引号
	case '\"':	//右双引号
		ret = 1;	//是需要检测的符号返回1
		break;
	default:
		ret = 0;	//不是需要检测的符号返回0
		break;
	}
	return ret;
}

int isLeft(char left)
{
	int ret = 0;
	switch (left)
	{
	case '<':	//左尖括号
	case '(':	//左小括号
	case '[':	//左中括号
	case '{':	//左大括号
	case '\'':	//左单引号
	case '\"':	//左双引号
		ret = 1;	//是需要检测的符号返回1
		break;
	default:
		ret = 0;	//不是需要检测的符号返回0
		break;
	}
	return ret;
}

int read(const char* code)
{
	int i = 0;
	LinkStack* stack = LinkStack_Create();

	while (code[i])
	{
		// 判断是否是左符号
		if (isLeft(code[i]))
		{
			// 是的话就压如栈中
			printf("push = %c\n", code[i]);
			LinkStack_Push(stack, (void*)&code[i]);
			//continue;
		}

		// 判断是否是右符号
		if (isRight(code[i]))
		{
			// 如果是则取出栈顶的符号与这个右符号对比
			char left = *(char*)LinkStack_Top(stack);
			if (match(left, code[i]))
			{
				// 匹配成功,从栈中弹出匹配过的左符号
				printf("pop  = %c\n", code[i]);
				LinkStack_Pop(stack);
			}
			else
			{
				// 匹配失败直接报错并终止循环
				printf("数据异常,匹配失败! left = %c, right = %c\n", left, code[i]);
				break;
			}
		}
		i++;
	}

	// 最后判断栈中是否还有数据,如果还有证明缺少右符号
	if (!LinkStack_Size(stack))
	{
		printf("匹配成功!\n");
	}
	else
	{
		char ch = *(char*)LinkStack_Top(stack);
		printf("缺少匹配 %c\n", ch);
	}
	// 销毁
	LinkStack_Destroy(stack);
	return 0;
}



int main(int argc, char* argv[])
{
	const char* code = "#include <stdio.h> int main() { int a[4][4]; int (*p)[4]; p = a[0]; return 0;}";
	read(code);

	return 0;
}

 

我本想将 STL 中各种容器的实现方法和作用全部写一遍,然后每种容器都发一篇文章,但后来发现这样做的意义不大,在 MSDN 或其他一些帮助文档中,他们比我写的要详细,其实我只需要记住每种容器的常用方法,和在什么场合选择合适的容器。下面这张表是我这里的一些常用方法集合。备用参考。继续阅读

atoi这个库函数实在的太强大了,很多细节上的处理是我们无法想象的,不过最近也尝试做了一下这个练习,发现真的不是那么简单,只实现了一部分功能。如将字符串”123″转换为123,”-0123″转换为-123。代码功能比较简陋,还有诸多没有实现的功能,相比库函数atoi还差的很多,仅供参考。继续阅读

有一个员工文件salary_back.txt,salary_back.txt文件每行 为部门职员的姓名:工资(如tom:20000),题目要求:

  1. 求出该公司有多少人。
  2. 从工资文件salary_back.txt中读入全部工人,全部增加100元工资后并保存信息到文件salary.txt中。
  3. 将加工资之后的所有员工按工资进行降序排序,将排序后的结果选出工资最高TOP10在屏幕上输出。

继续阅读