整理:字符串操作

本文介绍了C++中处理字符串的各种实用技巧,包括数字串转换、字符串复制、路径处理、环境变量获取、字符串翻转及比较等操作。通过具体示例展示了如何在不同场景下高效地使用字符串。

数字串转数字

int fnTest(){
//从FTP回答中过滤出返回码
CString csMsg;
int nRc = 0;
csMsg = "299自定义的FTP消息";
nRc = atol(csMsg);
printf("return code: %d/n", nRc);
//return code: 299
return S_OK;
}

在同一个Buffer上拷贝字符串

// testPrintBuffer.cpp : Defines the entry point for the console application.  
//  
#include "stdafx.h"  
#include <windows.h>  
int FnCopyOnSameBuffer(PBYTE pucDst, PBYTE pucSrc, DWORD dwLenNeedCopy);  
int FnPrintBuffer(PCHAR pcPrefix, PBYTE pbcBuffer, DWORD dwLenBuffer);  
int main(int argc, char* argv[])  {
DWORD dw = 0;
PBYTE pucBuffer = NULL;
DWORD dwLenBuffer = 0;
printf(">>Main\n");
dwLenBuffer = 0xff;
pucBuffer = new BYTE[dwLenBuffer];

//格式化数据
for(dw = 0; dw < dwLenBuffer; dw++)
{
 *(pucBuffer + dw) = (BYTE)(dw % 0x100);
}
printf("从同一段buffer的后面拷贝到前面\n");
FnPrintBuffer("拷贝前", pucBuffer, dwLenBuffer);
FnPrintBuffer("要拷贝的源数据", pucBuffer + 0x23, 0x45);
FnPrintBuffer("被覆盖前的目标数据", pucBuffer, 0x45);
FnCopyOnSameBuffer(pucBuffer, pucBuffer + 0x23, 0x45);//拷贝长度> 两指针之间的距离
FnPrintBuffer("拷贝后", pucBuffer, dwLenBuffer);
printf("<<Main\n");
getchar();
return 0;  }  int FnCopyOnSameBuffer(PBYTE pucDst, PBYTE pucSrc, DWORD dwLenNeedCopy)  {
memcpy(pucDst, pucSrc, dwLenNeedCopy);
return S_OK;  }  int FnPrintBuffer(PCHAR pcPrefix, PBYTE pbcBuffer, DWORD dwLenBuffer)  {
printf("//----------------------------------------\n");
printf("//提示信息:%s\n", pcPrefix);
printf("//字节流长度:%d\n", dwLenBuffer);
printf("//----------------------------------------\n");

ULONG i,j,m;
char buffer[0x100] = "\0";
char cBufTmp[8] = "\0";


strcpy(buffer,"");
m = dwLenBuffer%16;
//打印整行字符
for(i = 0; i < (dwLenBuffer -m); i++)
{
 //格式化16进制显示部分
 sprintf(cBufTmp, "%.2x", pbcBuffer[i]);
 _strupr(cBufTmp);
 strcat(buffer, cBufTmp);
 //每16个字符后面, 进行文本显示
 if (((i + 1) % 16) == 0)
 {
  strcat(buffer, " ");//隔断(16进制显示和文本显示)
  for(j = (i - 15); j < (i + 1); j++)
  {

sprintf(cBufTmp, "%c", isprint(pbcBuffer[j]) ? pbcBuffer[j] : '.' );

strcat(buffer,cBufTmp);
  }
  printf("%s\n", buffer);
  strcpy(buffer,"");
 }
}

if(m == 0)
{
 return S_OK;
}

//打印最后一行(不满16个字符)
strcpy(buffer, "");
for(i = dwLenBuffer - m; i < dwLenBuffer; i++)
{
 sprintf(cBufTmp, "%.2x", pbcBuffer[i]);
 _strupr(cBufTmp);
 strcat(buffer, cBufTmp);
}
//正文补齐
for(i = 0; i < (16 - m); i++)
{
 strcat(buffer,"  ");
}

strcat(buffer, " ");//隔断
for(j = (dwLenBuffer - m); j < dwLenBuffer; j++)
{
 sprintf(cBufTmp, "%c", isprint(pbcBuffer[j]) ? pbcBuffer[j] : '.' );
 strcat(buffer, cBufTmp);
}
strcat(buffer,"\n");
printf(buffer);
return S_OK;
}

拷贝前

拷贝后

比较拷贝效果

 

得到当前路径的简练写法

//得到的路径不带'//'结尾
CString s_CurDir;
GetCurrentDirectory(MAX_PATH, s_CurDir.GetBuffer(MAX_PATH));
s_CurDir.ReleaseBuffer();

 

分解字符串中的全路径名称

int SplitFilePathName(CString csPathName,
CString & csDriver,
CString & csDir,
CString & csFileNamePrefix,
CString & csFileNamePostfix)  {
//_splitpath 的反函数_makepath
_splitpath(csPathName.GetBuffer(csPathName.GetLength()),
  csDriver.GetBuffer(_MAX_DRIVE),
 csDir.GetBuffer(_MAX_DIR),
 csFileNamePrefix.GetBuffer(_MAX_FNAME),
 csFileNamePostfix.GetBuffer(_MAX_EXT));
csPathName.ReleaseBuffer();
csDriver.ReleaseBuffer();
csDir.ReleaseBuffer();
csFileNamePrefix.ReleaseBuffer();
csFileNamePostfix.ReleaseBuffer();
printf("%s = %s\n%s = %s\n%s = %s\n%s = %s\n%s = %s\n",
 "csPathName", csPathName,
 "csDriver", csDriver,
 "csDir", csDir,
 "csFileNamePrefix", csFileNamePrefix,
 "csFileNamePostfix", csFileNamePostfix);  /** note  * 运行结果:  * csPathName = c:\subDir1\subDir2\subDir3\test1.dat  * csDriver = c:  * csDir = \subDir1\subDir2\subDir3\  * csFileNamePrefix = test1  * csFileNamePostfix = .dat  */
return S_OK;  
}

 

<2010_1224>

CString to BSTR

/** @note* example: CString convert to BSTR*/
BSTR bstrFileName = m_strFileName.AllocSysString();
nLoadRc = Info.LoadFile(bstrFileName);
SysFreeString(bstrFileName);

BSTR to CString

/** @note* example: BSTR convert to CString*/
CString csOut;
BSTR bstrTmp;
get_Comments(&bstrTmp);
csOut = bstrTmp;

 

<2011_0102>

判断路径和文件的存在

#include <Shlwapi.h>
#pragma comment(lib, "Shlwapi.lib")
void CTestPathDlg::OnButtonJudgePath() {
// TODO: Add your control notification handler code here
int uSizePath = MAX_PATH;
PCHAR lpBufPath = new CHAR[uSizePath];
ZeroMemory(lpBufPath, uSizePath);
::GetWindowsDirectory(lpBufPath, uSizePath);
CString strPath = lpBufPath;
if(lpBufPath)delete lpBufPath;
if('//' != strPath.GetAt(strPath.GetLength() - 1))strPath += '//';
//framework 2.0 安装后的路径
strPath += "Microsoft.NET//Framework//v2.0.50727";
BOOL bRc = PathIsDirectory((LPSTR)(LPCSTR)strPath);
TRACE("判断全路径: 路径[%s]%s/n", (LPSTR)(LPCSTR)strPath, bRc ? "存在" : "不存在");
strPath += "//RegAsm.exe";
bRc = PathFileExists((LPSTR)(LPCSTR)strPath);
TRACE("判断全路径文件名称: 文件[%s]%s/n", (LPSTR)(LPCSTR)strPath, bRc ? "存在" : "不存在");
/*** 运行结果* 判断全路径: 路径[C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727]存在* 判断全路径文件名称: 文件[C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/RegAsm.exe]存在*/
}

得环境变量的值

void CTestPathDlg::OnButtonGetEnv() {
/*** 得环境变量的值*/
CString csPath;
int nLenPathMax = 4096;
PCHAR lpEnv = "APPDATA";
if(GetEnvironmentVariable(lpEnv, csPath.GetBuffer(nLenPathMax), nLenPathMax)){
TRACE("环境变量[%s]= [%s]/n", lpEnv, (LPSTR)(LPCSTR)csPath);
/*** 用的环境变量的方法, 可以用编程得到很多关于客户端计算机的有用信息* * 在cmd窗口中运行'set'命令, 可以看到Windows中环境变量的名称和值* * set的结果* ALLUSERSPROFILE=C:/Documents and Settings/All Users* APPDATA=C:/Documents and Settings/LostSpeed/Application Data* CommonProgramFiles=C:/Program Files/Common Files* COMPUTERNAME=LOSTSPEED-DEV* ComSpec=C:/WINDOWS/system32/cmd.exe* HOMEDRIVE=C:* HOMEPATH=/Documents and Settings/LostSpeed* JAVA_HOME=C:/Program Files/Java/jdk1.5.0_15* LOGONSERVER=//LOSTSPEED-DEV* MSDevDir=C:/Program Files/Microsoft Visual Studio/Common/MSDev98* NUMBER_OF_PROCESSORS=2* OS=Windows_NT* PROCESSOR_ARCHITECTURE=x86* PROCESSOR_IDENTIFIER=x86 Family 6 Model 15 Stepping 6, GenuineIntel* PROCESSOR_LEVEL=6* PROCESSOR_REVISION=0f06* ProgramFiles=C:/Program Files* SystemDrive=C:* SystemRoot=C:/WINDOWS* TEMP=C:/DOCUME~1/LOSTSP~1/LOCALS~1/Temp* TMP=C:/DOCUME~1/LOSTSP~1/LOCALS~1/Temp* USERDOMAIN=LOSTSPEED-DEV* USERNAME=LostSpeed* USERPROFILE=C:/Documents and Settings/LostSpeed* windir=C:/WINDOWS* * 运行结果:* 环境变量[APPDATA]= [C:/Documents and Settings/LostSpeed/Application Data]*/
}
}

csPath.GetBuffer() 后,要执行csPath.ReleaseBuffer();

 

<2011_0211>

在类中初始化常量串

google key word: "c++ class const variable"

 

<2011_0213>

打开临时文件夹

/*** 用资源管理器打开系统的临时文件夹*/
BOOL GetTempFolder(CString &strTempFolder){
const int MY_PATH_LEN_MAX = 4096;
PCHAR pcTmp = NULL;
pcTmp = strTempFolder.GetBuffer(MY_PATH_LEN_MAX);
GetTempPath(MY_PATH_LEN_MAX, pcTmp);
strTempFolder.ReleaseBuffer();
return TRUE;
}
void CGetTempDirPosDlg::OnButton1() {
// TODO: Add your control notification handler code here
CString csTmp;
GetTempFolder(csTmp);
ShellExecute(NULL, "Open", csTmp, NULL, NULL, SW_SHOW);
}

 

<2011_0310>

串翻转

// StringReverse.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <windows.h>
#include <algorithm>
int StringReverse1(PCHAR pcMsg, int nLenMsg);
int StringReverse2(PCHAR pcMsg, int nLenMsg);
int main(int argc, char* argv[]){
printf(">> main/n");
PCHAR pcMsg = new CHAR[1024];
strcpy(pcMsg, "please reverse a string");
int nLenMsg  = strlen(pcMsg);
/*** @note 用标准方法翻转字符串*/
printf("fn1 String original: [%s]/n", pcMsg);
StringReverse1(pcMsg, nLenMsg);
printf("fn1 String reverse 1: [%s]/n", pcMsg);
StringReverse1(pcMsg, nLenMsg);
printf("fn1 String reverse 2: [%s]/n", pcMsg);
/*** @note 用STL翻转字符串*/
printf("fn2 String original: [%s]/n", pcMsg);
StringReverse2(pcMsg, nLenMsg);
printf("fn2 String reverse 1: [%s]/n", pcMsg);
StringReverse2(pcMsg, nLenMsg);
printf("fn2 String reverse 2: [%s]/n", pcMsg);
if(pcMsg){
delete pcMsg;
pcMsg = NULL;
}
/** run results>> mainfn1 String original: [please reverse a string]fn1 String reverse 1: [gnirts a esrever esaelp]fn1 String reverse 2: [please reverse a string]fn2 String original: [please reverse a string]fn2 String reverse 1: [gnirts a esrever esaelp]fn2 String reverse 2: [please reverse a string]*/
getchar();
return 0;
}
int StringReverse2(PCHAR pcMsg, int nLenMsg){
std::reverse(pcMsg, pcMsg + nLenMsg);
return S_OK;
}
int StringReverse1(PCHAR pcMsg, int nLenMsg){
CHAR cTmp = '/0';
PCHAR pcStringBegin = pcMsg;
PCHAR pcStringEnd = pcMsg + nLenMsg - 1;
while(pcStringBegin < pcStringEnd){
cTmp = *pcStringBegin;
*pcStringBegin = *pcStringEnd;
*pcStringEnd = cTmp;pcStringBegin++;
pcStringEnd--;
}
return S_OK;
}

 <2011_0918>

TCHAR[] to tstring

TCHAR[] to tstring

#ifndef tstring
#ifdef _UNICODE
#define tstring std::wstring
#else
#define tstring std::string
#endif
#endif

tstring CFileNotify::GetFileNameFromFileNotify(PFILE_NOTIFY_INFORMATION pNotifyInfo)
{
	tstring str;
	if( pNotifyInfo )
	{
		WCHAR wcFileName[ MAX_PATH + 1] = {0};
		memcpy(	wcFileName,
			pNotifyInfo->FileName,
			min( (MAX_PATH * sizeof(TCHAR)), pNotifyInfo->FileNameLength));

                //暂时这样, 不知道还有没有更好的方法
		str.resize(min( (MAX_PATH * sizeof(TCHAR)), pNotifyInfo->FileNameLength) + sizeof(TCHAR));
		_stprintf_s((TCHAR *)str.c_str(), str.size() - 1, _T("%s"), wcFileName);

		_tprintf(_T("GetFileNameFromFileNotify = <%s>\n"), str.c_str());
	}

	return str;
}		

<2011_1026>

字符串比较

/** 字符串规范比较 */

#include "stdafx.h"
#include <windows.h>
#include <tchar.h>
#include <string>
#include <locale.h>
#include <algorithm>

#define G_STR_ALL _T("english:AbCdEfG;汉字: 一二三四五 符号: !=~")

//#define G_STR_OBJ1 _T("cDe") //ok, find it
#define G_STR_OBJ1 _T(";汉字")

#ifdef _UNICODE
#define tstring std::wstring
#else
#define tstring std::string
#endif

#define ERR_STR_NOT_FIND tstring::npos

/** tstring to 小写 */
TCHAR tchar2lower(TCHAR c);

/**
* @fn BOOL FindString(tstring strSrc, tstring strObj)
* @brief 在源串中寻找目标串, 支持中文和英文混写, 宽字符和ascii字符混写
* @param tstring strSrc, 源串
* @param tstring strObj, 目标串
* @param size_t & posFind, OUT 如果找到strObj, 返回strObj在strSrc的位置
* @return BOOL
* @retval TRUE, strSrc中包含strObj
* @retval FALSE, strSrc中不包含strObj
*/
BOOL FindString(tstring strSrc, tstring strObj, size_t & posFind);

int _tmain(int argc, _TCHAR* argv[])
{
    tstring strSrc;
    tstring strObj;
    size_t posFind = ERR_STR_NOT_FIND;

    _tsetlocale(LC_ALL, _T("Chinese_People's Republic of China.936"));
    strSrc = G_STR_ALL;
    strObj = G_STR_OBJ1;

    if(FindString(strSrc, strObj, posFind))
    {
        _tprintf(_T("找到目标字串\n"));

        _tprintf(_T("<%s>=<%s>\n"), _T("posFind string"), 
            strSrc.c_str() + posFind);
    }

    /** run results
    <strSrc>=<english:AbCdEfG;汉字: 一二三四五 符号: !=~>
    <strObj>=<;汉字>
    找到目标字串
    <posFind string>=<;汉字: 一二三四五 符号: !=~>
    */
    getchar();
    return 0;
}

BOOL FindString(tstring strSrc, tstring strObj, size_t & posFind)
{
    tstring strSrcCpy = strSrc;
    tstring strObjCpy = strObj;
    
    std::transform(strSrcCpy.begin(), strSrcCpy.end(), strSrcCpy.begin(), 
    tchar2lower);
    std::transform(strObjCpy.begin(), strObjCpy.end(), strObjCpy.begin(), 
    tchar2lower);

    posFind = strSrc.find(strObj);

    _tprintf(_T("<%s>=<%s>\n"), _T("strSrc"), strSrc.c_str());
    _tprintf(_T("<%s>=<%s>\n"), _T("strObj"), strObj.c_str());

    /** 串比较的规范方法 tstring::npos */
    return (ERR_STR_NOT_FIND != posFind) ? TRUE : FALSE;
}

TCHAR tchar2lower(TCHAR c)
{
    return (c >= _T('A') && c <= _T('Z')) ? c -('Z'-'z') : c;
} 


<2013_0917>

向剪贴板粘贴Unicode字符串

BOOL CopyTextToClipBoard(WCHAR * pcMsgW)
{
    BOOL    bRc = FALSE;
    HGLOBAL hClipboardData = NULL;
    WCHAR * pcDataW = NULL;

    if (!OpenClipboard(NULL))
        return FALSE;

    if (!EmptyClipboard())
        return FALSE;

    hClipboardData = GlobalAlloc(
        GMEM_DDESHARE, 
        (wcslen(pcMsgW) + 1) * sizeof(WCHAR));

    if (NULL != hClipboardData)
    {
        pcDataW = (WCHAR *)GlobalLock(hClipboardData);
        _tcscpy(pcDataW, pcMsgW);
        SetClipboardData(CF_UNICODETEXT, hClipboardData);
        GlobalUnlock(hClipboardData);
    }

    if (!CloseClipboard())
        return FALSE;

    return TRUE;
}


<2013-1001>

得到WinDir\System32目录的路径

/// @file       test.cpp
/// @brief      * use GetSystemDir(), to get System32 dir
///             * Load Dll on System32 dir

#include "stdafx.h"
#include <windows.h>
#include <tchar.h>
#include <string>

#ifndef SIZEOF_WCHAR_ARR
#define SIZEOF_WCHAR_ARR(x) \
    (sizeof(x) / sizeof(WCHAR))
#endif

BOOL LoadDllOnSystem32(HMODULE & hDll, const WCHAR * pcDllName);
BOOL GetSystemDir(std::wstring & strSysDir);

int _tmain(int argc, _TCHAR* argv[])
{
    HMODULE         hDll = NULL;
    const WCHAR *   pcDllName = L"RichEd20.DLL";

    if (!LoadDllOnSystem32(hDll, pcDllName))
        goto _tmain_END;

    _tprintf(L"use hDll do something ...\r\n");

_tmain_END:
    if (NULL != hDll)
        FreeLibrary(hDll);

    _tprintf(L"\r\nEND, press anykey to quit\r\n");
    getwchar();
    return 0;
}

BOOL GetSystemDir(std::wstring & strSysDir)
{
    UINT    uRc = 0;
    WCHAR   szDirPath[MAX_PATH];

    strSysDir = L"";
    uRc = ::GetSystemDirectoryW(szDirPath, SIZEOF_WCHAR_ARR(szDirPath));
    if (0 == uRc)
        return FALSE;

    szDirPath[uRc] = L'\0';
    strSysDir = szDirPath;

    return TRUE;
}

BOOL LoadDllOnSystem32(HMODULE & hDll, const WCHAR * pcDllName)
{
    BOOL            bRc = FALSE;
    std::wstring    strSysDir;
    
    hDll = NULL;
    if (!GetSystemDir(strSysDir))
        return bRc;

    strSysDir += L"\\";
    strSysDir += pcDllName;
    hDll = ::LoadLibrary(strSysDir.c_str());
    if (NULL != hDll)
        bRc = TRUE;

    return bRc;
}


 BSTR比较

                                /// <input class="inputStyle" type="text" name="xxx"></input>
                                if ((0 == _tcsicmp(bstrTagName, L"INPUT"))
                                    && (0 == _tcsicmp(bstrClassName, L"inputStyle"))
                                    && (0 == _tcsicmp(bstrType, L"text"))
                                    && (0 == _tcsicmp(bstrName, L"xxx")))
                                {
                                    /// find it, then set value to it
                                    pInputElem->put_value(L"xxx");
                                }

BSTR赋值

VARIANT myPath;
VariantInit(&myPath);

myPath.vt = VT_BSTR;
myPath.bstrVal = SysAllocString(it->c_str());

 

vParams[0].bstrVal = (BSTR)SysAllocString(T2BSTR(pcxx));  ///< pcxx是常量字符串

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值