C++的字符串分割函数

定义一个数据结构,其中成员有int len, char* internal_buf, char** strings。其中len是被分割后的字符串的个数,internal_buf用于保存原字符串。char** strings是字符串指针(或者你可以看做是指向字符数组的字符串指针,指针指向的类型是字符串,而不是单一的字符,char*strings[]),每个字符串指针用于保存被分割后的每个字符串的首地址。

#define STRING_TERMINATER '\0'

/*必须用完后调用free_sc_exlode_t释放内存,否则内存泄露*/
typedef struct sc_exlode_struct
{
    char** strings;
    int len;
    char* internal_buf;
} sc_exlode_t;

void free_sc_exlode_t(sc_exlode_t *string_array)
{
    if(NULL == string_array)
    {
        return;
    }
    free(string_array->internal_buf);
    free(string_array->strings);
    free(string_array);
}

void split_string(char delimiter, char *string ,sc_exlode_t *string_array)
{
    int count = 1;
    char *pchar, **ptr;

    if ( NULL != string_array)
    {
        memset(string_array, 0, sizeof(sc_exlode_t));
    }

    if(NULL == string || NULL == string_array)
    {
        return;
    }

    string_array->internal_buf = malloc(strlen(string) + 1);

    strcpy(string_array->internal_buf,string);
    if(NULL == string_array->internal_buf)
    {
        return;
    }

    pchar = string;
    while(STRING_TERMINATER != *pchar) //计算原字符串可以分割成的字符串个数
    {
        if (delimiter == *pchar)
        {
            count++;
        }
            pchar++;
    }
    string_array->strings = (char**)malloc(count*sizeof(char*));
    if(NULL == string_array->strings)
    {
        return;
    }
    string_array->len = count;

    ptr = string_array->strings;
    *ptr = string_array->internal_buf;
    pchar = string_array->internal_buf;
    while(STRING_TERMINATER != *pchar)
    {
        if (delimiter == *pchar)  //遇到指定字符时走此分支
        {
            ptr++;
            *ptr = pchar+1;
            *pchar = STRING_TERMINATER;
            pchar++;
                                               //每个ptr所指向的字符串末尾应该为'\0',
                                               //这样才能结束,所以将';'置为 '\0',
                                               //并让下一个字符串的首个字符地址,
                                               //即*ptr,指向‘;’后面的新字符串
                                               //的首地址。
    }
}
int main(void)
{
    sc_exlode_t *string_array = malloc(sizeof(sc_exlode_t));
    char *ip_range = "10.11.111.0;192.168.0.1;192.168.0.101";
    split_string(';', ip_range, string_array);
    printf("The spilited result: \n");

    for(int i=0;ilen;i++)
    {
        printf("%s\n",string_array->strings[i]);
    }
    free_sc_exlode_t(string_array);
    return 0;
}

C++/C中指针与数组的差别

C++/C中指针与数组的差别简述:
C++/C 程序中,指针和数组在不少地方可以相互替换着用,让人产生一种错觉,以
为两者是等价的。
数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。数组名对应着
(而不是指向)一块内存,其地址与容量在生命期内保持不变,只有数组的内容可以改
变。

指针可以随时指向任意类型的内存块,它的特征是“可变”,所以我们常用指针来
操作动态内存。指针远比数组灵活,但也更危险。

自定义firefox菜单栏字体(windows版本)

XP下的firefox界面的字体实在是太没美感了,即使给满目宋体的XP装了微软雅黑字体,但只能在一些允许自定义界面字体的软件上可以选择雅黑字体,firefox便是其中之一。

虽然可以在firefox的选项中对content设置,但是菜单栏,状态栏的字体甚至一些扩展的字体,比如echofon的字体也是宋体,看条twitter都觉得累,于是找来一个可以自定义firefox界面字体的方法:

当然,你喜欢的话,可以查看官方的说明:http://www.mozilla.org/unix/customizing.html

在C:\Documents and Settings\[User Name]\Application Data\Mozilla\Firefox\Profiles*******.default\chrome目录下面拷贝userChrome-example.css为 userChrome.css, 如我的就直接在文件中加入了下列内容:


menubar > menu, menubar, menubutton, menulist, menuitem {
 font-size: 12px !important;
 font-family: "Microsoft YaHei" !important;
}

dialog, box, button, page, label, caption, textbox, input, select {
 font-size: 12px !important;
 font-family: "Microsoft YaHei" !important;
}

menupopup > * {
 font-family: "Microsoft YaHei", Arial !important;
 font-size: 12px !important;
}

/*
 * Give the Location (URL) Bar a fixed-width font
 */
 #urlbar {
 font-family: "Microsoft YaHei" !important;
 font-size: 12px;
 }

window {
 font-size: 12px !important;
 font-family: "Microsoft YaHei" !important;
}

C/C++宏定义中的## 连接符与# 符

##连接符号由两个井号组成,其功能是在带参数的宏定义中将两个子串(token)联接起来,从而形成一个新的子串。但它不可以是第一个或者最后一个子串。所谓的子串(token)就是指编译器能够识别的最小语法单元。具体的定义在编译原理里有详尽的解释,但不知道也无所谓。同时值得注意的是#符是把传递过来的参数当成字符串进行替代。下面来看看它们是怎样工作的。这是MSDN上的一个例子。

假设程序中已经定义了这样一个带参数的宏:

#define paster( n ) printf( “token” #n ” = %d”, token##n )
同时又定义了一个整形变量:

int token9 = 9;
现在在主程序中以下面的方式调用这个宏:

paster( 9 );
那么在编译时,上面的这句话被扩展为:

printf( “token” “9″ ” = %d”, token9 );
注意到在这个例子中,paster(9);中的这个”9”被原封不动的当成了一个字符串,与”token”连接在了一起,从而成为了token9。而#n也被”9”所替代。

可想而知,上面程序运行的结果就是在屏幕上打印出token9=9

SQL连接查询

通过连接运算符可以实现多个表查询。连接是关系数据库模型的主要特点,也是它区别于其它类型数据库管理系统的一个标志。
连接可以在SELECT 语句的FROM子句或WHERE子句中建立,似是而非在FROM子句中指出连接时有助于将连接操作与WHERE子句中的搜索条件区分开来。所以,在Transact-SQL中推荐使用这种方法。

SQL-92标准所定义的FROM子句的连接语法格式为:

FROM join_table join_type join_table

[ON (join_condition)]

其中join_table指出参与连接操作的表名,连接可以对同一个表操作,也可以对多表操作,对同一个表操作的连接又称做自连接。

join_type 指出连接类型,可分为三种:内连接、外连接和交叉连接。内连接(INNER JOIN)使用比较运算符进行表间某(些)列数据的比较操作,并列出这些表中与连接条件相匹配的数据行。根据所使用的比较方式不同,内连接又分为等值连接、自然连接和不等连接三种。

外连接分为左外连接(LEFT OUTER JOIN或LEFT JOIN)、右外连接(RIGHT OUTER JOIN或RIGHT JOIN)和全外连接(FULL OUTER JOIN或FULL JOIN)三种。与内连接不同的是,外连接不只列出与连接条件相匹配的行,而是列出左表(左外连接时)、右表(右外连接时)或两个表(全外连接时)中所有符合搜索条件的数据行。

交叉连接(CROSS JOIN)没有WHERE 子句,它返回连接表中所有数据行的笛卡尔积,其结果集合中的数据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询条件的数据行数。

连接操作中的ON (join_condition) 子句指出连接条件,它由被连接表中的列和比较运算符、逻辑运算符等构成。

无论哪种连接都不能对text、ntext和image数据类型列进行直接连接,但可以对这三种列进行间接连接。例如:

SELECT p1.pub_id,p2.pub_id,p1.pr_info

FROM pub_info AS p1 INNER JOIN pub_info AS p2

ON DATALENGTH(p1.pr_info)=DATALENGTH(p2.pr_info)

(一)内连接
Read the rest of this entry »