1. 程式人生 > >C/C++ 常用的函式與方法

C/C++ 常用的函式與方法

1,建立多級目錄

#include <string>
#include <direct.h> //_mkdir函式的標頭檔案
#include <io.h>     //_access函式的標頭檔案
using namespace std;
void CreateDir( const char *dir )
{
    int m = 0, n;
    string str1, str2;
    str1 = dir;
    str2 = str1.substr( 0, 2 );
    str1 = str1.substr( 3, str1.size() );
    while
( m >= 0 ) { m = str1.find('\\'); str2 += '\\' + str1.substr( 0, m ); n = _access( str2.c_str(), 0 ); //判斷該目錄是否存在 if( n == -1 ) { _mkdir( str2.c_str() ); //建立目錄 } str1 = str1.substr( m+1, str1.size() ); } } int main(int
argc, char* argv[]) { char dir[] = "E:\\Demo\\Folder\\subFolder\\my"; CreateDir( dir ); return 0; } //或者使用WinAPI MakeSureDirectoryPathExists

2,獲取exe所在目錄

#include <Windows.h>
#include <atlstr.h>
void GetExePath(char *pBuffer)
{
    GetModuleFileNameA(NULL,(LPSTR)pBuffer,MAX_PATH);
    PathRemoveFileSpecA(pBuffer);
}

3,不區分大小寫的strstr

const char * stristr(const char * str1,const char * str2)
{
    char *cp = (char *)str1;
    char *s1, *s2;
    if (!*str2)
        return((char *)str1);
    while (*cp)
    {
        s1 = cp;
        s2 = (char *)str2;
        while (*s1 && *s2 && (!(*s1 - *s2) || !(*s1 - *s2 - 32) || !(*s1 - *s2 + 32))) {
            s1++, s2++;
        }
        if (!*s2)
            return(cp);
        cp++;
    }
    return nullptr;
}

4,wstring轉string

std::string ConvertWStringToAnsi(std::wstring wstr)
{
    std::string result;
    int len = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.size(), NULL, 0, NULL, NULL);
    if (len <= 0)
        return result;
    char* buffer = new char[len + 1];
    if (buffer == NULL)
        return result;
    WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.size(), buffer, len, NULL, NULL);
    buffer[len] = '\0';               //字串斷尾
    result.append(buffer);            //賦值
    delete[] buffer;                  //刪除緩衝區
    return result;
}

5,string轉wstring

std::wstring ConvertAnsiToWString(std::string str)
{
    std::wstring result;

    int len = MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), NULL, 0);
    if (len < 0)
        return result;

    wchar_t* buffer = new wchar_t[len + 1];
    if (buffer == NULL)
        return result;

    MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), buffer, len);

    buffer[len] = '\0';                    //字串斷尾
    result.append(buffer);                 //賦值
    delete[] buffer;                       //刪除緩衝區
    return result;
}

6,獲取登錄檔值

std::string GetRegValue(int nKeyType, const std::string& strUrl, const std::string& strKey)
{
    std::string strValue("");
    HKEY hKey = NULL;
    HKEY  hKeyResult = NULL;
    DWORD dwSize = 0;
    DWORD dwDataType = 0;
    std::string wstrUrl = strUrl;
    std::string wstrKey = strKey;

    switch (nKeyType)
    {
    case 0:
    {
        hKey = HKEY_CLASSES_ROOT;
        break;
    }
    case 1:
    {
        hKey = HKEY_CURRENT_USER;
        break;
    }
    case 2:
    {
        hKey = HKEY_LOCAL_MACHINE;
        break;
    }
    case 3:
    {
        hKey = HKEY_USERS;
        break;
    }
    case 4:
    {
        hKey = HKEY_PERFORMANCE_DATA;
        break;
    }
    case 5:
    {
        hKey = HKEY_CURRENT_CONFIG;
        break;
    }
    case 6:
    {
        hKey = HKEY_DYN_DATA;
        break;
    }
    case 7:
    {
        hKey = HKEY_CURRENT_USER_LOCAL_SETTINGS;
        break;
    }
    case 8:
    {
        hKey = HKEY_PERFORMANCE_TEXT;
        break;
    }
    case 9:
    {
        hKey = HKEY_PERFORMANCE_NLSTEXT;
        break;
    }
    default:
    {
        return strValue;
    }
    }

    //開啟登錄檔
    if (ERROR_SUCCESS == ::RegOpenKeyEx(hKey, wstrUrl.c_str(), 0, KEY_QUERY_VALUE, &hKeyResult))
    {
        // 獲取快取的長度dwSize及型別dwDataType
        ::RegQueryValueEx(hKeyResult, wstrKey.c_str(), 0, &dwDataType, NULL, &dwSize);
        switch (dwDataType)
        {
        case REG_MULTI_SZ:
        {
            //分配記憶體大小
            BYTE* lpValue = new BYTE[dwSize];
            //獲取登錄檔中指定的鍵所對應的值
            LONG lRet = ::RegQueryValueEx(hKeyResult, wstrKey.c_str(), 0, &dwDataType, lpValue, &dwSize);
            delete[] lpValue;
            break;
        }
        case REG_SZ:
        {
            //分配記憶體大小
            char * lpValue = new char[dwSize];
            memset(lpValue, 0, dwSize);
            //獲取登錄檔中指定的鍵所對應的值
            if (ERROR_SUCCESS == ::RegQueryValueEx(hKeyResult, wstrKey.c_str(), 0, &dwDataType, (LPBYTE)lpValue, &dwSize))
            {
                strValue = lpValue;
            }
            delete lpValue;
            break;
        }
        default:
            break;
        }
    }   //關閉登錄檔
    ::RegCloseKey(hKeyResult);
    return strValue;
}

7,設定登錄檔值


bool SetRegStrValue(HKEY type,const char *pLocation, const char * szItem,const char * szWriteKey,const char*szValue)
{
    HKEY hkey;//定義有關的hkey,在查詢結束時要關閉  
    HKEY hTempKey;
    bool bValue = true;

    if (ERROR_SUCCESS == RegOpenKeyEx(type, pLocation, 0, KEY_SET_VALUE, &hkey))
    {
        if (ERROR_SUCCESS == ::RegCreateKey(hkey, szItem, &hTempKey))
        {
            if (ERROR_SUCCESS != ::RegSetValueEx(hTempKey, szWriteKey, 0, REG_SZ, (CONST BYTE*)szValue, strlen(szValue)+1))
            {
                bValue = false;
            }
        }
    }
    ::RegCloseKey(hkey);
    return bValue;
}

8,拆分字串

std::vector<std::string> splitString(std::string srcStr, std::string delimStr,bool repeatedCharIgnored)
{
    std::vector<std::string> resultStringVector;
    std::replace_if(srcStr.begin(), srcStr.end(), [&](const char& c){if(delimStr.find(c)!=std::string::npos){return true;}else{return false;}}/*pred*/, delimStr.at(0));//將出現的所有分隔符都替換成為一個相同的字元(分隔符字串的第一個)
    size_t pos=srcStr.find(delimStr.at(0));
    std::string addedString="";
    while (pos!=std::string::npos) {
        addedString=srcStr.substr(0,pos);
        if (!addedString.empty()||!repeatedCharIgnored) {
            resultStringVector.push_back(addedString);
        }
        srcStr.erase(srcStr.begin(), srcStr.begin()+pos+1);
        pos=srcStr.find(delimStr.at(0));
    }
    addedString=srcStr;
    if (!addedString.empty()||!repeatedCharIgnored) {
        resultStringVector.push_back(addedString);
    }
    return resultStringVector;
}

9,GBK轉UTF-8,vs編譯的dll給Qt來呼叫,需要轉一個字符集

std::string GBKToUTF8(const std::string& strGBK)
{
    std::string strOutUTF8 = "";
    WCHAR * str1;
    int n = MultiByteToWideChar(CP_ACP, 0, strGBK.c_str(), -1, NULL, 0);
    str1 = new WCHAR[n];
    MultiByteToWideChar(CP_ACP, 0, strGBK.c_str(), -1, str1, n);
    n = WideCharToMultiByte(CP_UTF8, 0, str1, -1, NULL, 0, NULL, NULL);
    char * str2 = new char[n];
    WideCharToMultiByte(CP_UTF8, 0, str1, -1, str2, n, NULL, NULL);
    strOutUTF8 = str2;
    delete[]str1;
    str1 = NULL;
    delete[]str2;
    str2 = NULL;
    return strOutUTF8;
}

10,字串替換

void string_replace( std::string &strBig, const std::string &strsrc, const std::string &strdst )
{
 std::string::size_type pos = 0;
 std::string::size_type srclen = strsrc.size();
 std::string::size_type dstlen = strdst.size();

 while( (pos=strBig.find(strsrc, pos)) != std::string::npos )
 {
  strBig.replace( pos, srclen, strdst );
  pos += dstlen;
 }
} 

11,好用的執行cmd命令

#include <windows.h>

#include <iostream>  
#include <corecrt_io.h>
using namespace std;
// 描述:execmd函式執行命令,並將結果儲存到result字串陣列中   
// 引數:cmd表示要執行的命令  
// result是執行的結果儲存的字串陣列  
// 函式執行成功返回1,失敗返回0    
int execmd(const char* cmd, char* result) {
    char buffer[128];                         //定義緩衝區                          
    FILE* pipe = _popen(cmd, "r");            //開啟管道,並執行命令   
    if (!pipe)
        return 0;                      //返回0表示執行失敗   

    while (!feof(pipe)) {
        if (fgets(buffer, 128, pipe)) {             //將管道輸出到result中   
            strcat(result, buffer);
        }
    }
    _pclose(pipe);                            //關閉管道   
    return 1;                                 //返回1表示執行成功   
}

int main()
{
    char buffer[1024] = {0};
    if (1 == execmd("netsh winsock reset", buffer))
    {
        printf(buffer);
    }
    else
    {
        ::MessageBox(NULL,L"",L"",NULL);
    }
    return 0;
}

12,刪除所有目錄

BOOL IsDirectory(const char *pDir)
{
    char szCurPath[500];
    ZeroMemory(szCurPath, 500);
    sprintf_s(szCurPath, 500, "%s//*", pDir);
    WIN32_FIND_DATAA FindFileData;
    ZeroMemory(&FindFileData, sizeof(WIN32_FIND_DATAA));

    HANDLE hFile = FindFirstFileA(szCurPath, &FindFileData); /**< find first file by given path. */

    if (hFile == INVALID_HANDLE_VALUE)
    {
        FindClose(hFile);
        return FALSE; /** 如果不能找到第一個檔案,那麼沒有目錄 */
    }
    else
    {
        FindClose(hFile);
        return TRUE;
    }
}

BOOL DeleteDirectory(const char * DirName)
{
    char szCurPath[MAX_PATH];        //用於定義搜尋格式
    _snprintf(szCurPath, MAX_PATH, "%s\\*.*", DirName);    //匹配格式為*.*,即該目錄下的所有檔案
    WIN32_FIND_DATAA FindFileData;
    ZeroMemory(&FindFileData, sizeof(WIN32_FIND_DATAA));
    HANDLE hFile = FindFirstFileA(szCurPath, &FindFileData);
    BOOL IsFinded = TRUE;
    while (IsFinded)
    {
        IsFinded = FindNextFileA(hFile, &FindFileData);    //遞迴搜尋其他的檔案
        if (strcmp(FindFileData.cFileName, ".") && strcmp(FindFileData.cFileName, "..")) //如果不是"." ".."目錄
        {
            std::string strFileName = "";
            strFileName = strFileName + DirName + "\\" + FindFileData.cFileName;
            std::string strTemp;
            strTemp = strFileName;
            if (IsDirectory(strFileName.c_str())) //如果是目錄,則遞迴地呼叫
            {
                printf("目錄為:%s/n", strFileName.c_str());
                DeleteDirectory(strTemp.c_str());
            }
            else
            {
                DeleteFileA(strTemp.c_str());
            }
        }
    }
    FindClose(hFile);

    BOOL bRet = RemoveDirectoryA(DirName);
    if (bRet == 0) //刪除目錄
    {
        printf("刪除%s目錄失敗!/n", DirName);
        return FALSE;
    }
    return TRUE;
}

13,copy目錄下所有檔案到另一個目錄下

void CopyFiles(const char* lpPath, const char *pFolder)
{
    char szFind[MAX_PATH] = { 0 };
    WIN32_FIND_DATA FindFileData;

    strcpy(szFind, lpPath);
    strcat(szFind, "\\*.*");

    HANDLE hFind = ::FindFirstFile(szFind, &FindFileData);
    if (INVALID_HANDLE_VALUE == hFind)    return;

    while (true)
    {
        if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
        {
            if (FindFileData.cFileName[0] != '.')
            {
                char szFile[MAX_PATH];
                strcpy(szFile, lpPath);
                strcat(szFile, (char*)(FindFileData.cFileName));
                CopyFiles(szFile, pFolder);
            }
        }
        else
        {
            //std::cout << FindFileData.cFileName << std::endl;
            std::string strTemp = lpPath;
            strTemp += FindFileData.cFileName;


            std::string strDest = pFolder;
            strDest += FindFileData.cFileName;

            CopyFileA(strTemp.c_str(), strDest.c_str(), FALSE);
        }
        if (!FindNextFile(hFind, &FindFileData))    break;
    }
    FindClose(hFind);
}

程式實現自刪除


#include<windows.h>  
#include<ShlObj.h>  
#include <tchar.h>  
#include <shellapi.h>


VOID DelItself()
{
    SHELLEXECUTEINFO stShellDel;
    TCHAR szBat[MAX_PATH];

    //獲取檔案路徑名  
    TCHAR szFileName[MAX_PATH], szComspec[MAX_PATH];
    if ((GetModuleFileName(0, szFileName, MAX_PATH) != 0) &&
        (GetShortPathName(szFileName, szFileName, MAX_PATH) != 0) &&
        (GetEnvironmentVariable("COMSPEC", szComspec, MAX_PATH) != 0))
    {
        lstrcpy(szBat, "/c del ");
        lstrcat(szBat, szFileName);
        lstrcat(szBat, " > nul");

        stShellDel.cbSize = sizeof(stShellDel);

        //命令視窗程序控制代碼,ShellExecuteEx函式執行時設定。   
        stShellDel.hwnd = 0;
        stShellDel.lpVerb = "Open";
        stShellDel.lpFile = szComspec;
        stShellDel.lpParameters = szBat;
        stShellDel.lpDirectory = NULL;
        stShellDel.nShow = SW_HIDE;

        //設定為SellExecuteEx函式結束後進程退出。   
        stShellDel.fMask = SEE_MASK_NOCLOSEPROCESS;

        //建立執行命令視窗程序。   
        if (ShellExecuteEx(&stShellDel))
        {
            //設定命令列程序的執行級別為空閒執行,這使本程式有足夠的時間從記憶體中退出。   
            SetPriorityClass(stShellDel.hProcess, IDLE_PRIORITY_CLASS);

            //設定本程式程序的執行級別為實時執行,這保證本程式能立即獲取CPU執行權,快速退出。   
            SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
            SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);

            //通知Windows資源管理器,本程式檔案已經被刪除。   
            SHChangeNotify(SHCNE_DELETE, SHCNF_PATH, szFileName, 0);
            ExitProcess(0);
        }
    }

}

清空目錄

BOOL EmptyDirectory(const char * lpszPath)
{
    SHFILEOPSTRUCT FileOp;
    ZeroMemory((void *)& FileOp, sizeof(SHFILEOPSTRUCT));
    FileOp.fFlags = FOF_NOCONFIRMATION | FOF_SILENT;
    FileOp.hNameMappings = NULL;
    FileOp.hwnd = NULL;
    FileOp.lpszProgressTitle = NULL;
    char tempPath[256] = { 0 };
    //使用萬用字元
    memcpy(tempPath, lpszPath, strlen(lpszPath)); memcpy(&tempPath[strlen(lpszPath)], "//*", strlen("//*"));
    FileOp.pFrom =tempPath;
    FileOp.pTo = NULL;
    FileOp.wFunc = FO_DELETE;
    return SHFileOperation(&FileOp) == 0;
}

copy 目錄

void copydir(char* src, char* dst)
{
    WIN32_FIND_DATAA FindFileData;
    HANDLE hFind;
    char tmpsrc[256];
    strcpy(tmpsrc, src);
    strcat(tmpsrc, "\\*.*");
    hFind = FindFirstFileA(tmpsrc, &FindFileData);
    if (hFind == INVALID_HANDLE_VALUE)
        return;
    CreateDirectoryA(dst, 0);
    do
    {
        char newdst[256];
        strcpy(newdst, dst);
        if (newdst[strlen(newdst)] != '\\')
            strcat(newdst, "\\");
        strcat(newdst, FindFileData.cFileName);


        char newsrc[256];
        strcpy(newsrc, src);
        if (newsrc[strlen(newsrc)] != '\\')
            strcat(newsrc, "\\");
        strcat(newsrc, FindFileData.cFileName);
        if (FindFileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
        {
            if (strcmp(FindFileData.cFileName, ".") != 0 && strcmp(FindFileData.cFileName, "..") != 0)
            {
                copydir(newsrc, newdst);
            }
        }
        else
        {
            CopyFileA(newsrc, newdst, false);
        }
    } while (FindNextFileA(hFind, &FindFileData));
    FindClose(hFind);
}   std::string strDest = pFolder;
            strDest += FindFileData.cFileName;

            CopyFileA(strTemp.c_str(), strDest.c_str(), FALSE);
        }
        if (!FindNextFileA(hFind, &FindFileData))    break;
    }
    FindClose(hFind);
}

去除檔案目錄檔名

1、完整路徑,去除字尾名   PathRemoveExtensionA

[cpp] view plain copy
#include <iostream>//cout函式所需  
#include "atlstr.h"  //PathRemoveExtensionA函式所需  

using namespace std;  

void main(void)  
{  
    char buffer_1[] = "C:\\TEST\\sample.txt";  
    char *lpStr1;  
    lpStr1 = buffer_1;  
    cout << "The path with extension is          : " << lpStr1 << endl;  
    PathRemoveExtensionA(lpStr1);  
    cout << "\nThe path without extension is       : " << lpStr1 << endl;  
    system("pause");  
}  
OUTPUT:
==================
The path with extension is          : C:\TEST\sample.txt
The path without extension is       : C:\TEST\sample

2、完整檔案路徑,獲得目錄

[cpp] view plain copy
#include <iostream>//cout函式所需  
#include "atlstr.h"  //PathRemoveFileSpecA函式所需  

using namespace std;  

void main(void)  
{  
    char buffer_1[] = "C:\\TEST\\sample.txt";  
    char *lpStr1;  
    lpStr1 = buffer_1;  
    cout << "The path with file spec is          : " << lpStr1 << endl;  
    PathRemoveFileSpecA(lpStr1);  
    cout << "\nThe path without file spec is       : " << lpStr1 << endl;  
    //注意如果獲得了目錄,需要得到另一個檔案路徑時  
    string filename = lpStr1;  
    filename = filename + "\\samle.txt";  
    system("pause");  
}  
OUTPUT:
==================
The path with file spec is          : C:\TEST\sample.txt
The path without file spec is       : C:\TEST

清空目錄的示例:

 // Delete szSrcFile next time system is rebooted   MoveFileEx(szSrcFile, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);