当前位置:C++技术网 > 精选软件 > 获取删除字符后的字符串的两种方法

获取删除字符后的字符串的两种方法

更新时间:2016-01-01 20:41:20浏览次数:1+次

    在文章《win32使用退格键BackSpace从后到前的删除字符串的字符》中,我们分析了删除字符串的效果的实现。删除字符串也使用了两种方法,两种方法各有千秋,在实现时差别很大,那么在获取删除字符后的字符串,自然也有很大的差别。这个涉及到两种代码实现思维,所以在此详细讲讲。所以本篇重点是分析实现方法,说的是项目开发的实现思维。

    两种实现删除字符效果不一样,获取删除后的字符串也不一样,我们都分析一下。下面是实现的程序的效果图:

两种方法获取删除字符后的字符串都是一样的,右键获取并显示被删除后的字符串

【两种方法获取删除字符后的字符串都是一样的,右键获取并显示被删除后的字符串】
    第一种就是直接在原始字符串上删除。这种方式是真正意义上的删除。删除实现方法分析见开头提到的文章的分析。那么这样删除后,原始字符串就自然而然是删除后的字符串。基于这样的实现方法,如果只是用于删除字符串的字符和获取删除字符串的字符后的字符串,自然是最方便的。我们只要返回这个原始字符串地址即可。
    然而,我们要知道,在原始字符上操作,往往就破坏了原始的数据。这一点在实际开发中,很多时候是不合适的。因为一旦误操作,我们都想着去恢复一下。如果原 始字符串都删掉了,如何恢复。当然,我们就想到了使用待删除字符串的副本来操作。这样的话,也就对原始的数据做了一个保护,可用于恢复。当用户误删了字符 串,你可以提供一次性全部恢复,也可以逐个字符的恢复。当然一次性全部恢复字符串是最简单的,只要将原始字符串拷贝一份即可恢复。当然,对于逐个的恢复删 除的字符串,也是可以的,你只要增加一个删除字符的个数的计数即可。然后恢复一次,就恢复一个字符,也就是将原始字符串的字符复制到被操作的字符串中对应 的位置即可。
    那么第一种方法在提供额外的辅助功能时就比较麻烦,要增加额外的开销,比如待删除的字符串的副本。
    第二种方法就是只是减少要显示的字符串的字符数。因 为删除是从后往前删除的,而且我们也可以知道删除的次数。这样就可以得到删除后的字符数,然后用这个字符数来显示字符串。这样的实现,并没有真正的删除字 符串,只是一个障眼法而已。如果用户误删了,要一次性全部恢复,只要将删除字符的数目设置为0即可。如果要逐个字的恢复,则将删除字符数逐个的递减即可。 由此看来,对于提供的辅助性功能有比较好的支持。这样在编辑中可以快速反复的删除和恢复,因为不用对内存的原始字符串操作,只是改变被删除的字符的计数, 所以体验更好点。
    然而第二种删除字符串的字符后,原始字符串并没有修改,所以我们要获取被删除字符串的字符后的字符串,则要通过被删除的字符数来确定最终的字符串有多少个 字符,也就是用总字符数减去被删除的字符数即可。我们可以在最终的确定字符串时,将剩下的字符串提取出来,也可以用一个同样的字符串来提取。
    第 一种方法开始处理比较麻烦点,第二种方法在得到删除后的字符串时比较麻烦,当然,哪个更好用,取决于你需要的功能偏向哪个,灵活选取。这里只提供一个基本 的思路而已,其实还可以有更多的灵活的实现,比如可以直接拷贝字符串即可提取被删除的字符串,无须额外增加一个字符数组等。两种实现获取删除字符后的字符 串的方法,一个是前期麻烦,后期简单,另一个相反。前期是指删除字符的实时显示以及恢复字符串,后期是指获取删除字符后的字符串。恢复字符串就只说了方 法,简单的代码实现就没有写了。如果要实现撤销功能,使用第二种最方便,因为只需要修改被删除的字符数就行了。
    下面是完整的获取删除字符后的字符串的代码:
#include "windows.h"
#include <tchar.h>
// - 项目是Unicode字符集
TCHAR cjjjs[100]=_T("C++技术网http:www.cjjjs.com");
TCHAR tip[100]=_T("提示:按下键盘的←(退格键)可以删除了字符");
LRESULT CALLBACK WinProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    static RECT rect;
    static int iDelCount=0;
    switch (message)
    {
     case WM_PAINT:
         hdc = BeginPaint(hwnd,&ps);
         SelectObject(hdc,GetStockObject(SYSTEM_FIXED_FONT));
         TextOut(hdc,0,0,cjjjs,lstrlen(cjjjs)-iDelCount);
         TextOut(hdc,0,50,tip,lstrlen(tip));
         EndPaint(hwnd,&ps);
         return 0;
     case WM_KEYDOWN:
        if (VK_BACK==wParam)
        {
            //直接在原字符串上删除
            //int len = lstrlen(cjjjs);
            //if (len!=0)
            //{
            //    cjjjs[len-1]=_T(');
            //}
            //只是减少显示的字符个数,原字符串不受影响
            iDelCount++;
        }
         InvalidateRect(hwnd,NULL,TRUE);
         return 0;
     case WM_RBUTTONDOWN:
         {
             //方法1:
             //MessageBox(hwnd,cjjjs,_T("方法1:被删除后的字符串"),0);

             //方法2
             TCHAR cjjjs_del[100]=_T("C++技术网http:www.cjjjs.com");
             int iLeft = lstrlen(cjjjs)-iDelCount;
             cjjjs_del[iLeft]=_T(');
             MessageBox(hwnd,cjjjs_del,_T("方法2:被删除后的字符串"),0);
         }
         return 0;
     case WM_DESTROY:
         PostQuitMessage(0);
         return 0;
     default:
         return DefWindowProc(hwnd, message, wParam, lParam);
    }
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrev,LPSTR lpCmd,int iShow)
{
    TCHAR ClassName[] = _T("MyClass");
    TCHAR title1[] = _T("C++技术网http://www.cjjjs.com");
    WNDCLASS wndClass;
    wndClass.cbClsExtra=0;
    wndClass.cbWndExtra=0;
    wndClass.hbrBackground= (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndClass.hCursor=LoadCursor(NULL,IDC_HAND);
    wndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
    wndClass.hInstance = hInstance;
    wndClass.lpfnWndProc = WinProc;
    wndClass.lpszClassName = ClassName;
    wndClass.lpszMenuName=NULL;
    wndClass.style=CS_HREDRAW|CS_VREDRAW;

    if(!RegisterClass(&wndClass))return 0;
    HWND hwnd = CreateWindow(ClassName,title1,WS_OVERLAPPEDWINDOW,0,0,440,400,NULL,NULL,hInstance,NULL);
    ShowWindow(hwnd,SW_SHOWNORMAL);

    MSG msg;
    while (GetMessage(&msg,NULL,0,0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}