最后更新于 .

之前已经写过一篇vim正则表达式查找替换,今天我们继续来写vim正则表达式查找替换(2),主要是一些代码编写中可能用到的查找替换技巧,希望对大家有用。

1.删除行尾的空白字符(包括空格和tab)

:%s/\s\+$//

2.删除空白行

:g/^[ ,\t]*$/d

3.压缩空白行(即两行变成一行)

:%s/^\n\+/\r/

4.压缩重复行(即重复的行变成一行,只能两行两行的压缩)

%s/^\(.*\)\n\1$/\1/

从而可以得知,匹配重复2行的命令是:

/^\(.*\)\n\1

重复3行的命令是:

/^\(.*\)\n\1\n\1

5.删除行尾的^M字符(dos换行符)

%s/\r//g

OK,就这么多,以后有了新的就再总结啦~《vim正则表达式查找替换》我会继续写下去,争取做成一个系列~

最后更新于 .

在程序中,我们经常性的会使用到时间格式的转化,比如讲time_t转化成string,或者反过来转,下面就是实现的代码。

分为 2009-3-24 和 2009-3-24 0:00:08两种时间格式。
时间格式:2009-3-24 :

#include <sys/time.h>
/*
    string to time_t
    时间格式  2009-3-24
*/
int API_StringToTime(const string &strDateStr,time_t &timeData)
{
    char *pBeginPos = (char*) strDateStr.c_str();
    char *pPos = strstr(pBeginPos,"-");
    if(pPos == NULL)
    {
        return -1;
    }
    int iYear = atoi(pBeginPos);
    int iMonth = atoi(pPos + 1);

    pPos = strstr ...

最后更新于 .

在linux下面,我们不得不自己写makefile,makefile的确博大精深,但是实际上对于日常的使用来说,无非就是
1:编译可执行程序。2:编译lib库 3:编译so库
本博针对上面三种目的各自写出了makefile模版,希望对大家有所帮助。
一.编译可执行程序
当前目录下制定文件编译成可执行文件(连接外部库的话只需要更改INC和LIB即可)

CXX = g++
TARGET = bitmaploctest
C_FLAGS += -g -Wall
LIB_FLAGS = -pthread
all: $(TARGET)
bitmaploctest: bitmaploctest.o bitmaploc.o file_lock.o
    $(CXX) -o $@ $^ $(LIB_FLAGS) $(LIB) $(C_FLAGS)
.cpp.o:
    $(CXX) -c -o $*.o $(INC) $(C_FLAGS) $*.cpp
.cc.o:
    $(CXX) -c -o $*.o ...

最后更新于 .

经常会用到gbk和utf8互转的情况,下面的代码就是实现了这样的功能,希望对大家有用~  

//GBK 2 UTF8
int API_Gbk2Utf8(const char *szSource, string &strDest)
{
    char szUniString[strlen(szSource)*2];
    int iLen = string_gbk2unicode(szSource, szUniString, strlen(szSource));
    unsigned char pTemp[4] = {0};
    unsigned short iTemp;
    char *pUTFString = (char *)malloc(sizeof(szUniString) *2+1);
    int pos=0;
    for (int i=0; i<iLen; i++)
    {
        iTemp =(((unsigned char)szUniString ...

最后更新于 .

在工作中,我们可能经常会用到压力测试等循环执行执行发包的机制,为了防止目标机压力过大,必然需要一个限速逻辑来进行控制,之前在网上看了看,发现基本没有这方面的介绍,于是自己写了一个。 这段代码使用了已经大半年,基本能够满足各种限速的要求,其中的动态调整逻辑也能够保证对限速本身对cpu的消耗不会太大,希望对大家有所帮助。(ps:这段代码是在linux下使用的,当然只需要将获取时间的函数改一下,那么在windows下也可以使用的,如果有朋友改了记得通知我一下哦~~)

#include <sys/time.h>
#include <stdio.h>
#include <math.h>
#include <iostream>
struct timeval tpstart,tpend;
int timeuse;
gettimeofday(&tpstart,NULL);
int countPerSec=0;//计算请求数
int statCount;//统计用
int iMaxReqPerSec=100;//最大限速
int trueMaxReq=iMaxReqPerSec;//动态调整的判定大小
while(1)
{
    //业务要做的事情 ...

最后更新于 .

远程登录服务器用vim在终端下编辑查看文件经常会遇见各种中文乱码问题。

做如下设置可基本解决vim中文乱码问题

首先查看系统对中文的支持

locale -a | grep zh_CN

输出样例如下

zh_CN.gbk zh_CN.utf8

vim 只能正确识别列表中的中文编码文件,如需识别其他编码类型的中文文件,则需要做系统升级

vi ~/.bash_profile 文件末尾添加

export LANG="zh_CN.UTF-8" 或者"en_US.UTF-8"

export LC_ALL="zh_CN.UTF-8"  或者"en_US.UTF-8"

vi ~/.vimrc 文件末尾添加

let &termencoding=&encoding

set fileencodings=utf-8,gbk,utf-16,big5

(这里是优先做了utf-8的模式判断,当然也可以优先做gbk,这里在我之前的文章里面都有讲)

修改SecureCRT设置 options->appearance  character encoding 改为utf-8

当然你也可以修改全局配置的appearance   options->global ...

最后更新于 .

有人在Quake III的源代码里面发现这么一段用来求平方根的代码:

float Q_rsqrt( float number )
{
	long i;
	float x2, y;
	const float threehalfs = 1.5F;
	x2 = number * 0.5F;
	y  = number;
	i  = * ( long * ) &y; // evil floating point bit level hacking
	i  = 0x5f3759df - ( i >> 1 ); // what the fuck?
	y  = * ( float * ) &i;
	y  = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration
//	y  = y * ( threehalfs - ( x2 * y ...

最后更新于 .

一直在linux下开发的人一定会用到tcpdump,下面就是关于tcpdump的使用方法说明 (1). tcpdump的选项

-a       将网络地址和广播地址转变成名字;
-d       将匹配信息包的代码以人们能够理解的汇编格式给出;
-dd      将匹配信息包的代码以c语言程序段的格式给出;
-ddd     将匹配信息包的代码以十进制的形式给出;
-e       在输出行打印出数据链路层的头部信息;
-f       将外部的Internet地址以数字的形式打印出来;
-l       使标准输出变为缓冲行形式;
-n       不把网络地址转换成名字;
-t       在输出的每一行不打印时间戳;
-v       输出一个稍微详细的信息,例如在ip包中可以包括ttl和服务类型的信息;
-vv      输出详细的报文信息;
-c       在收到指定的包的数目后,tcpdump就会停止;
-F       从指定的文件中读取表达式,忽略其它的表达式;
-i       指定监听的网络接口;
-r       从指定的文件中读取包(这些包一般通过-w选项产生);
-w       直接将包写入文件中,并不分析和打印出来;
-T       将监听到的包直接解释为指定的类型的报文,常见的类型有rpc (远程过程调用)和snmp(简单网络管理协议;)

(2). tcpdump的表达式 表达式是一个正则表达式,tcpdump利用它作为过滤报文的条件,如果一个报文满足表达式的条件,则这个报文将会被捕获。如果没有给出任何条件,则网络上所有的信息包将会被截获 ...

最后更新于 .

connect中使用了select模型,有如下地方需要注意:
我们提供的server api中有很多地方用到了select,特别是在等超时的时候,
例如:
fd_set recv_fds;
int iNum= 0;
if (m_iSocket <0) return -1;
FD_ZERO( &recv_fds );
FD_SET( m_iSocket, &recv_fds );
iNum= select( m_iSocket+1, &recv_fds, NULL, NULL, timeout );
return iNum;
这段代码对于cgi,或者简单的逻辑server不会有问题。但是对于多线程或者复杂的server可能会导致server core掉。
原因是select默认只支持1024个句柄,每个句柄采用和1024个bit对应的关系,如果fd的值超过1024,那么就会溢出。
也就是说,如果上面代码的m_iSocket>1024,那么后面的select就会溢出,即使只监听一个句柄也会溢出。奇怪的是select也不会报错。
而对于多线程或者大连接的server很有可能分配的fd超过1024.
所以建议以后写的api尽量有poll或者epoll的方式。
有poll改写了下面的代码:
int waittime = (timeout->tv_sec*1000)+(timeout->tv_usec/1000.0);
struct ...

最后更新于 .

阻塞方式block,就是进程或是线程执行到这些函数时必须等待某个事件的发生,如果事件没有发生,进程或线程就被阻塞,函数不能立即返回。使用Select就可以完成非阻塞non-block,就是进程或线程执行此函数时不必非要等待事件的发生,一旦执行肯定返回,以返回值的不同来反映函数的执行情况,如果事件发生则与阻塞方式相同,若事件没有发生则返回一个代码来告知事件未发生,而进程或线程继续执行,所以效率较高。select能够监视我们需要监视的文件描述符的变化情况。

(一)首先说明两个结构体:
1:struct fd_set一个存放文件描述符(file descriptor),即文件句柄的聚合,实际上是一long类型的数组,
每一个数组元素都能与一打开的文件句柄(不管是Socket句柄,还是其他文件或命名管道或设备句柄)建立联系,建立联系的工作由程序员完成;
 

FD_ZERO(fd_set *fdset):清空fdset与所有文件句柄的联系。
FD_SET(int fd, fd_set *fdset):建立文件句柄fd与fdset的联系。
FD_CLR(int fd, fd_set *fdset):清除文件句柄fd与fdset的联系。
FD_ISSET(int fd, fdset *fdset):检查fdset联系的文件句柄fd是否可读写,>0表示可读写。

2:struct timeval用来代表时间值 ...