cyycoish 发表于 2015-7-4 22:31:22

【C】C语言版的vb字符串函数库

最近用C自己写词法分析器
词法分析器的标准写法是构建自动机进行正则匹配
然而我不走寻常路,自己使用字符串函数拆解字符串
因为我的第一次已经给了vb(请大家不要:{:soso_e127:} )
所以vb的字符串函数已经扔不掉了,这次用C重写了vb大多数字符串函数。

文件名叫做:cvbstrfun.h,大家只需包含该头文件即可

/////////////////////////////////////////////////
//                Description:               //
//            C Style VB Str Func            //
//            Name:cvbstrfun.h               //
//               Auther:Cyycoish               //
//            ID:201506282102A               //
//          (C) 2015 www.0xaa55.com            //
//            All Rights Reserved.             //
/////////////////////////////////////////////////
#include <locale.h>
#include <wchar.h>
#include <tchar.h>
#include <malloc.h>
#define WCHR wchar_t
//________________________
//|   <Function Table>   |
//|______________________|
//|C Style    |VB Style|
//|-----------|----------|
//|wslen      |Len       |
//|wsucase    |UCase   |
//|wsleft   |Left      |
//|wsinverse|StrReverse|
//|wsright    |Right   |
//|wsmid      |Mid       |
//|wsinstr    |InStr   |
//|wsltrim    |LTrim   |
//|wsrtrim    |RTrim   |
//|wsinstrrev |InStrRev|
//|___________|__________|
int wslen(WCHR* s)
{
        return wcslen(s);
}
void wsucase(WCHR* s)
{
        int i;
        for (i = 0; i <= wcslen(s) - 1; i++)
                s = towupper(s);
        return;
}
void wslcase(WCHR* s)
{
        int i;
        for (i = 0; i <= wcslen(s) - 1; i++)
                s = towlower(s);
        return;
}
WCHR* wsleft(WCHR* szTar, int n)
{
        int i;
        WCHR* rtn;
        WCHR tmpWChr = {'\0', '\0'};
        if (n > wcslen(szTar))
                return L"";
        rtn = (WCHR*)malloc(sizeof(szTar));
        wcscpy(rtn, L"");
        for (i = 0; i <= n - 1; i++)
        {
                tmpWChr = szTar;
                wcscat(rtn, tmpWChr);
        }
        return rtn;
}
void wsinverse(WCHR* szTar)
{
        int i, j, l;
        WCHR* rtn;
        WCHR tmpWChr = {'\0', '\0'};
        l = wcslen(szTar);
        rtn = (WCHR*)malloc(sizeof(szTar));
        wcscpy(rtn, L"");
        for (i = 0, j = l - 1; i < wcslen(szTar); i++, j--)
        {
                rtn = szTar;
        }
        rtn = '\0';
        wcscpy(szTar, rtn);
}
WCHR* wsright(WCHR* szTar, int n)
{
        int i, j, l;
        WCHR* rtn;
        WCHR tmpWChr = {'\0', '\0'};
        l = wcslen(szTar);
        if (n > l)
                return L"";
        rtn = (WCHR*)malloc(sizeof(szTar));
        wcscpy(rtn, L"");
        for (i = l - 1, j = 1; j <= n; i--, j++)
        {
                tmpWChr = szTar;
                wcscat(rtn, tmpWChr);
        }
        wsinverse(rtn);
        return rtn;
}
WCHR* wsmid(WCHR* szTar, int st, int n)
{
        int i;
        WCHR* rtn;
        WCHR tmpWChr = {'\0', '\0'};
        if ((st - 1 + n) > wcslen(szTar))
                return L"";
        rtn = (WCHR*)malloc(sizeof(szTar));
        wcscpy(rtn, L"");

        for (i = st - 1; i <= st + n - 2; i++)
        {
                tmpWChr = szTar;
                wcscat(rtn, tmpWChr);
        }
        return rtn;
}
int wsinstr(WCHR* szTar, WCHR* szCmp, int st)
{
        int i;
        if (st >= wcslen(szTar) - wcslen(szCmp))
                return -1;
        for (i = st; i <= wcslen(szTar); i++)
        {
                if (!wcscmp(szCmp, wsmid(szTar, i, wcslen(szCmp))))
                        return i;
        }
        return -1;
}
void wsltrim(WCHR* szTar)
{
        int i;
        int b = 0;
        WCHR* rtn;
        WCHR tmpWChr = {'\0', '\0'};
        rtn = (WCHR*)malloc(sizeof(szTar));
        wcscpy(rtn, L"");
        for (i = 0; i < wcslen(szTar); i++)
        {
                tmpWChr = szTar;
                if (tmpWChr != ' ' || b != 0)
                {
                        wcscat(rtn, tmpWChr);
                        if (tmpWChr != ' ' && b == 0)
                                b = !(b);
                }
        }
        wcscpy(szTar, rtn);
}
void wsrtrim(WCHR* szTar)
{
        int i, j, l;
        int b = 0;
        WCHR* rtn;
        WCHR tmpWChr = {'\0', '\0'};
        l = wcslen(szTar);
        rtn = (WCHR*)malloc(sizeof(szTar));
        wcscpy(rtn, L"");
        for (i = l - 1, j = 1; j < l; i--, j++)
        {
                tmpWChr = szTar;
                if (tmpWChr != ' ' || b != 0)
                {
                        wcscat(rtn, tmpWChr);
                        if (tmpWChr != ' ' && b == 0)
                                b = !(b);
                }
        }
        wsinverse(rtn);
        wcscpy(szTar, rtn);
}
int wsinstrrev(WCHR* szTar, WCHR* szCmp, int st)
{
        int i;
        WCHR* s1, * s2;
        s1 = (WCHR*)malloc(sizeof(szTar));
        s2 = (WCHR*)malloc(sizeof(szCmp));
        wcscpy(s1, szTar); wcscpy(s2, szCmp);
        wsinverse(s1); wsinverse(s2);
        if (st >= wcslen(szTar) - wcslen(szCmp))
                return -1;
        for (i = st; i < wcslen(szTar); i++)
        {
                if (!wcscmp(s2, wsmid(s1, i, wcslen(s2))))
                {
                        return wcslen(szTar) - i + 1;
                }
        }
        return -1;
}

还有一点 大家需要注意的是:
因为是宽字符,所以main函数调用该头文件,使用函数时要locate一下,具体做法如下:
#include <stdio.h>
#include "cvbstrfun.h"

int _tmain(int argc, wchar_t* argv[])
{
       
        WCHR str[] = {L"abcdefg"};
        //int a;
        setlocale(LC_CTYPE, ""); //就是这个关键的一句,不加显示不了中文
        //wcscpy(str, wsleft(str, 2));
        //wsinverse(str);
        //wcscpy(str, wsright(str, 3));
        //wcscpy(str, wsmid(str, 3, 2));
        //wsucase(str);
        //wsrtrim(str);
        //a = wsinstrrev(L"aabccccc", L"b", 1);
        //wprintf(L"\"%s\"\n", str);
        //printf("\n%d\n", a);
       
        return 0;
}

0xAA55 发表于 2015-7-5 12:45:06

哪天你再实现一下strstr strcpy strchr strcmp sprintf等函数的VB版本吧。
嘛。我开玩笑的。不必为此浪费时间哦。

0x01810 发表于 2015-7-7 16:22:02

wsinverse 函数里的 rtn 是忘记释放的节奏?

cyycoish 发表于 2015-7-7 22:34:54

0x01810 发表于 2015-7-7 16:22
wsinverse 函数里的 rtn 是忘记释放的节奏?

这个rtn不可以释放啊
wcscpy是直接传地址的
rtn free掉了以后,szTar就木有了:loveliness:

cyycoish 发表于 2015-7-7 22:36:30

重写了一下wsinstrrev:
int wsinstrrev(const WCHR* szTar, const WCHR* szCmp, int st)
{
        int i;
        for (i = wcslen(szTar) - wcslen(szCmp) + 1; i >= st; i--)
                if (!wcscmp(szCmp, wsmid(szTar, i, wcslen(szCmp))))
                        return i;
        return -1;
}

0x01810 发表于 2015-7-8 14:41:35

cyycoish 发表于 2015-7-7 22:34
这个rtn不可以释放啊
wcscpy是直接传地址的
rtn free掉了以后,szTar就木有了 ...

不是应该这样写吗:

void wsinverse(WCHAR* szTar)
{
        int i, j, l;
        WCHAR* rtn;
        l = wcslen(szTar);
        rtn = (WCHAR*)malloc(sizeof(szTar));
        wcscpy(rtn, L"");
        for (i = 0, j = l - 1; i < wcslen(szTar); i++, j--)
        {
                rtn = szTar;
        }
        rtn = '\0';
        wcscpy(szTar, rtn);
        free(rtn);
}

cyycoish 发表于 2015-7-8 17:14:03

0x01810 发表于 2015-7-8 14:41
不是应该这样写吗:

void wsinverse(WCHAR* szTar)


wsinverse是这样声明的:void wsinverse(WCHAR* szTar) 如果调用wsinverse,函数修改的是原本传入的那个字符串。然后,在函数内部,有这么一句:wcscpy(szTar, rtn);。咱们来看一下wcscpy的声明:wchar_t * __cdecl wcscpy(wchar_t * _Dest, const wchar_t * _Source)。这样一来rtn所指向的地址就完完全全给了szTar,换句话说,刚刚传入的那个字符串的内存地址变成了malloc出来的rtn所指向的地址。如果这时候free,相当于free了传入字符串的地址。打个简单的比方吧:我借了你的作业,作业本到手以后,因为某种原因,我不小心把你的字全擦了。后来呢,我又叫A5帮你重写了一遍。这时候,若要擦掉A5写的的作业,就等于擦掉了你的本子上所有的内容,你也就拿着一个空本子了。@0xAA55 <=A5惨遭背锅:P

cyycoish 发表于 2015-7-8 17:27:44

呐,最新版本:
#include <locale.h>
#include <wchar.h>
#include <tchar.h>
#include <malloc.h>
#define WCHR wchar_t
//String Functions
int wslen(const WCHR* s)
{
        return wcslen(s);
}
void wsucase(WCHR* s)
{
        int i;
        for (i = 0; i <= wcslen(s) - 1; i++)
                s = towupper(s);
        return;
}
void wslcase(WCHR* s)
{
        int i;
        for (i = 0; i <= wcslen(s) - 1; i++)
                s = towlower(s);
        return;
}
WCHR* wsleft(const WCHR* szTar, int n)
{
        int i;
        WCHR* rtn;
        WCHR tmpWChr = {'\0', '\0'};
        if (n > wcslen(szTar))
                return L"";
        rtn = (WCHR*)malloc(sizeof(szTar));
        wcscpy(rtn, L"");
        for (i = 0; i <= n - 1; i++)
        {
                tmpWChr = szTar;
                wcscat(rtn, tmpWChr);
        }
        return rtn;
}
void wsinverse(WCHR* szTar)
{
        int i, j, k;
        WCHR* rtn;
        WCHR tmpWChr = {'\0', '\0'};
        k = wcslen(szTar);
        rtn = (WCHR*)malloc(sizeof(szTar));
        wcscpy(rtn, L"");
        for (i = 0, j = k - 1; i < wcslen(szTar); i++, j--)
        {
                rtn = szTar;
        }
        rtn = '\0';
        wcscpy(szTar, rtn);
}
WCHR* wsright(const WCHR* szTar, int n)
{
        int i, j, l;
        WCHR* rtn;
        WCHR tmpWChr = {'\0', '\0'};
        l = wcslen(szTar);
        if (n > l)
                return L"";
        rtn = (WCHR*)malloc(sizeof(szTar));
        wcscpy(rtn, L"");
        for (i = l - 1, j = 1; j <= n; i--, j++)
        {
                tmpWChr = szTar;
                wcscat(rtn, tmpWChr);
        }
        wsinverse(rtn);
        return rtn;
}
WCHR* wsmid(const WCHR* szTar, int st, int n)
{
        int i;
        WCHR* rtn;
        WCHR tmpWChr = {'\0', '\0'};
        if ((st - 1 + n) > wcslen(szTar))
                return L"";
        rtn = (WCHR*)malloc(sizeof(szTar));
        wcscpy(rtn, L"");

        for (i = st - 1; i <= st + n - 2; i++)
        {
                tmpWChr = szTar;
                wcscat(rtn, tmpWChr);
        }
        return rtn;
}
int wsinstr(const WCHR* szTar, const WCHR* szCmp, int st)
{
        int i;
        if (st >= wcslen(szTar) - wcslen(szCmp))
                return -1;
        for (i = st; i <= wcslen(szTar); i++)
        {
                if (!wcscmp(szCmp, wsmid(szTar, i, wcslen(szCmp))))
                        return i;
        }
        return -1;
}
void wsltrim(WCHR* szTar)
{
        int i;
        int b = 0;
        WCHR* rtn;
        WCHR tmpWChr = {'\0', '\0'};
        rtn = (WCHR*)malloc(sizeof(szTar));
        wcscpy(rtn, L"");
        for (i = 0; i < wcslen(szTar); i++)
        {
                tmpWChr = szTar;
                if (tmpWChr != ' ' || b != 0)
                {
                        wcscat(rtn, tmpWChr);
                        if (tmpWChr != ' ' && b == 0)
                                b = !(b);
                }
        }
        wcscpy(szTar, rtn);
}
void wsrtrim(WCHR* szTar)
{
        int i, j, l;
        int b = 0;
        WCHR* rtn;
        WCHR tmpWChr = {'\0', '\0'};
        l = wcslen(szTar);
        rtn = (WCHR*)malloc(sizeof(szTar));
        wcscpy(rtn, L"");
        for (i = l - 1, j = 1; j < l; i--, j++)
        {
                tmpWChr = szTar;
                if (tmpWChr != ' ' || b != 0)
                {
                        wcscat(rtn, tmpWChr);
                        if (tmpWChr != ' ' && b == 0)
                                b = !(b);
                }
        }
        wsinverse(rtn);
        wcscpy(szTar, rtn);
}
int wsinstrrev(const WCHR* szTar, const WCHR* szCmp, int st)
{
        int i;
        for (i = wcslen(szTar) - wcslen(szCmp) + 1; i >= st; i--)
                if (!wcscmp(szCmp, wsmid(szTar, i, wcslen(szCmp))))
                        return i;
        return -1;
}
//End String Functions

0xAA55 发表于 2015-7-8 18:54:54

cyycoish 发表于 2015-7-8 17:27
呐,最新版本:
#include
#include


@0x01810 说得对。那个地址确实要释放。你只是分配了一块内存用于临时存储翻转后的字符串而已。用完后,你需要释放这块内存。

cyycoish 发表于 2015-7-8 20:20:52

0xAA55 发表于 2015-7-8 18:54
@0x01810 说得对。那个地址确实要释放。你只是分配了一块内存用于临时存储翻转后的字符串而已。用完后, ...

但是。。。释放后就。。。。

0xAA55 发表于 2015-7-8 20:24:53

cyycoish 发表于 2015-7-8 20:20
但是。。。释放后就。。。。

rtn = (WCHR*)malloc(sizeof(szTar));
其中szTar是个指针,也就是说,sizeof(szTar)的值,x86的时候是4,x64的时候是8,然后它的前后有malloc的一些数据,被你来个缓冲区溢出,破坏了。自然,free也不能成功。
这不是VB,这是C,你需要把sizeof(szTar)改成字符串的实际长度。

cyycoish 发表于 2015-7-8 21:42:31

终于,在站长的指导下完成了50%,这里要特别感谢A5站长@0xAA55
算是一次阶段性的成功:
/////////////////////////////////////////////////
//                Description:               //
//            String Functions               //
//                Name:StrFun.h                //
//            Auther:Cosh Cage               //
//            ID:201507082140C               //
/////////////////////////////////////////////////
#include <locale.h>
#include <wchar.h>
#include <tchar.h>
#include <malloc.h>

#define WCHR wchar_t
/*
int   wslen   (const WCHR* s);
voidwsucase   (WCHR* s);
voidwslcase   (WCHR* s);
WCHR* wsleft    (const WCHR* szTar, int n);
voidwsinverse (WCHR* szTar);
WCHR* wsright   (const WCHR* szTar, int n);
WCHR* wsmid   (const WCHR* szTar, int st, int n);
int   wsinstr   (const WCHR* szTar, const WCHR* szCmp, int st);
voidwsltrim   (WCHR* szTar);
voidwsrtrim   (WCHR* szTar);
int   wsinstrrev(const WCHR* szTar, const WCHR* szCmp, int st);
*/
//String Functions
int wslen(const WCHR* s)
{
        return wcslen(s);
}
void wsucase(WCHR* s)
{
        int i;
        for (i = 0; i <= wcslen(s) - 1; i++)
                s = towupper(s);
        return;
}
void wslcase(WCHR* s)
{
        int i;
        for (i = 0; i <= wcslen(s) - 1; i++)
                s = towlower(s);
        return;
}
WCHR* wsleft(const WCHR* szTar, int n)
{
        int i;
        WCHR* rtn;
        WCHR tmpWChr = {'\0', '\0'};
        if (n > wcslen(szTar))
                return L"";
        rtn = (WCHR*)malloc(sizeof(WCHR) * (wcslen(szTar) + 1));
        wcscpy(rtn, L"");
        for (i = 0; i <= n - 1; i++)
        {
                tmpWChr = szTar;
                wcscat(rtn, tmpWChr);
        }
        return rtn;
}
void wsinverse(WCHR* szTar)
{
        int i, j, k;
        WCHR* rtn;
        k = wcslen(szTar);
        rtn = (WCHR*)malloc(sizeof(WCHR) * (k + 1));
        for (i = 0, j = k - 1; i < wcslen(szTar); i++, j--)
        {
                rtn = szTar;
        }
        rtn = '\0';
        wcscpy(szTar, rtn);
        free(rtn);
}
WCHR* wsright(const WCHR* szTar, int n)
{
        int i, j, k;
        WCHR* rtn;
        WCHR tmpWChr = {'\0', '\0'};
        k = wcslen(szTar);
        if (n > k)
                return L"";
        rtn = (WCHR*)malloc(sizeof(WCHR) * (k + 1));
        wcscpy(rtn, L"");
        for (i = k - 1, j = 1; j <= n; i--, j++)
        {
                tmpWChr = szTar;
                wcscat(rtn, tmpWChr);
        }
        wsinverse(rtn);
        return rtn;
}
WCHR* wsmid(const WCHR* szTar, int st, int n)
{
        int i;
        WCHR* rtn;
        WCHR tmpWChr = {'\0', '\0'};
        if ((st - 1 + n) > wcslen(szTar))
                return L"";
        rtn = (WCHR*)malloc(sizeof(WCHR) * (wcslen(szTar) + 1));
        wcscpy(rtn, L"");

        for (i = st - 1; i <= st + n - 2; i++)
        {
                tmpWChr = szTar;
                wcscat(rtn, tmpWChr);
        }
        return rtn;
}
int wsinstr(const WCHR* szTar, const WCHR* szCmp, int st)
{
        int i;
        if (st >= wcslen(szTar) - wcslen(szCmp))
                return -1;
        for (i = st; i <= wcslen(szTar); i++)
        {
                if (!wcscmp(szCmp, wsmid(szTar, i, wcslen(szCmp))))
                        return i;
        }
        return -1;
}
void wsltrim(WCHR* szTar)
{
        int i;
        int b = 0;
        WCHR* rtn;
        WCHR tmpWChr = {'\0', '\0'};
        rtn = (WCHR*)malloc(sizeof(WCHR) * (wcslen(szTar) + 1));
        wcscpy(rtn, L"");
        for (i = 0; i < wcslen(szTar); i++)
        {
                tmpWChr = szTar;
                if (tmpWChr != ' ' || b != 0)
                {
                        wcscat(rtn, tmpWChr);
                        if (tmpWChr != ' ' && b == 0)
                                b = !(b);
                }
        }
        wcscpy(szTar, rtn);
        free(rtn);
}
void wsrtrim(WCHR* szTar)
{
        int i, j, k;
        int b = 0;
        WCHR* rtn;
        WCHR tmpWChr = {'\0', '\0'};
        k = wcslen(szTar);
        rtn = (WCHR*)malloc(sizeof(WCHR) * (k + 1));
        wcscpy(rtn, L"");
        for (i = k - 1, j = 0; j < k; i--, j++)
        {
                tmpWChr = szTar;
                if (tmpWChr != ' ' || b != 0)
                {
                        wcscat(rtn, tmpWChr);
                        if (tmpWChr != ' ' && b == 0)
                                b = !(b);
                }
        }
        wsinverse(rtn);
        wcscpy(szTar, rtn);
        free(rtn);
}
int wsinstrrev(const WCHR* szTar, const WCHR* szCmp, int st)
{
        int i;
        for (i = wcslen(szTar) - wcslen(szCmp) + 1; i >= st; i--)
                if (!wcscmp(szCmp, wsmid(szTar, i, wcslen(szCmp))))
                        return i;
        return -1;
}
//End String Functions
页: [1]
查看完整版本: 【C】C语言版的vb字符串函数库