C++ 常用&生僻函數小記

string類

find函數

四種函數原型:

1)size_t find (const string& str, size_t pos = 0) const;  //查找對象--string類對象2)size_t find (const char* s, size_t pos = 0) const; //查找對象--字符串3)size_t find (const char* s, size_t pos, size_t n) const;  //查找對象--字符串的前n個字符4)size_t find (char c, size_t pos = 0) const;  //查找對象--字符
  • -rfind() 與之類似,只是從反向查找
  • -返回值 :
    • 找到返回 第一個字符的索引
    • 沒找到返回 string::npos
    #include <string>  
    #include <iostream>  
    using namespace std;  

    int main()  
    {  
        string strFirst ( "abced" ),strSecond("abc abc abd def");  
        cout<<strFirst.find("a")<<endl;//輸出結果爲0,說明a當前的索引位置爲0  

        //函數原型:size_type find_first_not_of( Char ch, size_type index = 0 ) const;  
        //返回在字符串中首次不匹配 d 的首字符索引,從2開始。  
        cout<<strFirst.find_first_not_of ( "d" ,2)<<endl;   //輸出結果爲 2     

        cout<<strSecond.length()<<endl;//輸出結果爲15  
        cout<<strSecond.find_first_not_of("abc",4)<<endl;   //輸出結果爲7  
        system("pause");  
    }  

find_first_of

[函數原型]

size_type find_first_of( const basic_string &str, size_type pos= 0 ); 
size_type find_first_of( const char *str, size_type pos= 0 ); 
size_type find_first_of( const char *str, size_type pos, size_type num ); 
size_type find_first_of( char ch, size_type pos= 0 ); 

[說明]
查找在字符串中第一個與str中的某個字符匹配的字符,返回它的位置。搜索從index開始,如果沒找到就返回string::npos ;
查找在字符串中第一個與str中的某個字符匹配的字符,返回它的位置。搜索從index開始,最多搜索num個字符。如果沒找到就返回string::npos;
查找在字符串中第一個與ch匹配的字符,返回它的位置。搜索從index開始;

substr函數

原型:

string.substr(size_t startpos, size_tlength);

其中 startpos 是起始字符的序號,length 是[從 startpos 開始]取的字符串長度(包括startpos )。
如果要取得 str 中序號 m 到 n 之間(不包括n)的子字符串需要用str.substr(m, n-m);
示例代碼:

#include<string>
#include<iostream>
using namespace std;

main()
{
string s("12345asdf");
string a=s.substr(0,4);       //獲得字符串s中 從第0位開始的長度爲4的字符串
cout<<a<<endl;
}

輸出結果:
1234

動態載入DLL相關函數


DLL是Dynamic Link Library的縮寫,意爲動態鏈接庫。在Windows中,許多應用程序並不是一個完整的可執行文件,它們被分割成一些相對獨立的動態鏈接庫,即DLL文件,放置於系統中。當我們執行某一個程序時,相應的DLL文件就會被調用。
動態載入方式是指在編譯之前並不知道將會調用哪些 DLL 函數, 完全是在運行過程中根據需要決定應調用哪些函數。
方法是:用 LoadLibrary 函數加載動態鏈接庫到內存,用 GetProcAddress函數動態獲得 DLL 函數的入口地址。當一個 DLL 文件用 LoadLibrary 顯式加載後,在任何時刻均可以通過調用 FreeLibrary 函數顯式地從內存中把它給卸載。
動態調用使用的 Windows API 函數主要有 3 個, 分別是 LoadLibrary、 GetProcAddress 和FreeLibrary。

實例代碼:

    #include <stdio.h>  

    #include <stdlib.h>  
    #include <windows.h>  

    //假如CreateDll.dll這個dll中有一個函數Add(int a, int b);  

    //定義一個函數指針  
    typedef int (*func_Add)(int a, int b);  

    int main(int argc, char *argv[])   
    {  
        int sum = 0;  
        HMODULE h = NULL;  
        func_Add func_Add_from_dll = NULL;  

        //注意dll的路徑,視自己的情況而定  
        h = LoadLibrary("..\\CreateDll\\CreateDll.dll");  
        if(NULL == h)  
        {  
            printf("LoadLibrary failed!\n");  
            return 0;  
        }  

        func_Add_from_dll = (func_Add)GetProcAddress(h, "Add");  
        if(NULL == func_Add_from_dll)  
        {  
            printf("GetProcAddress failed!\n");  
            return 0;  
        }  

        sum = (*func_Add_from_dll)(1, 2);     
        printf("%d\n", sum);  

        getchar();  
        return 0;  
    }  

LoadLibrary函數


原型:

    HMODULE LoadLibrary(char * LibFileName)  

[功能]:加載由參數 LibFileName 指定的 DLL 文件。
[返回值]:返回裝載 DLL 庫模塊的實例句柄。
[說明]:參數 LibFileName 指定了要裝載的 DLL 文件名,如果 LibFileName 沒有包含一個路徑,系統將按照:當前目錄、Windows 目錄、Windows 系統目錄、包含當前任務可執行文件的目錄、列在 PATH 環境變量中的目錄等順序查找文件。

如果函數操作成功,將返回裝載 DLL 庫模塊的實例句柄,否則,將返回一個錯誤代碼

注意:假如在應用程序中用 LoadLibrary 函數裝入某一個 DLL 前, 其他應用程序已把該 DLL 裝入內存中了,則系統將不再裝入該 DLL 的另一個實例,而是使該 DLL 的“引用計數”加 1 。

GetProcAddress函數


原型:

    func_pointer GetProcAddress(HMODULE h,char * func_name)  

[功能]:返回參數 h指定的模塊中(由LoadLibrary函數返回的指向DLL模塊的參數),由參數 func_name指定的過程或函數的入口地址。
[說明]:參數 h包含被調用函數的 DLL 句柄,這個值由 LoadLibrary 返回, func_name是指向含有函數名的以 nil 結尾的字符串指針,或者可以是函數的次序值,但大多數情況下,用函數名是一種更穩妥的選擇。

如果該函數執行成功,則返回 DLL 中由參數 func_name指定的過程或函數的入口地址,否則返回 nil 。

FreeLibrary函數


原型:

    FreeLibrary(HMODULE h)  

[說明]:將由參數 h指定的 DLL 文件從內存中卸載 1 次。h爲 DLL 庫的句柄。這個值由 LoadLibrary 返回。由於 DLL 在內存中只裝載一次,因此調用 FreeLibrary 首先使 DLL 的引用計數減 1,如果計數減爲 0 則卸載該 DLL。

注意:每調用一次 LoadLibrary 函數就應調用一次 FreeLibrary 函數,以保證不會有多餘的庫模塊在應用程序結束後仍留在內存中,否則導致內存泄漏。

getopt函數


示例代碼:

    #include <stdio.h>  
    #include <unistd.h>  

    int main(int argc,char *argv[])  
    {  
      int ch;  
      opterr=0;  

      while((ch=getopt(argc,argv,"a:b::cde"))!=-1)  
      {  
        printf("optind:%d\n",optind);  
        printf("optarg:%s\n",optarg);  
        printf("ch:%c\n",ch);  
        switch(ch)  
        {  
          case 'a':  
            printf("option a:'%s'\n",optarg);  
            break;  
          case 'b':  
            printf("option b:'%s'\n",optarg);  
            break;  
          case 'c':  
            printf("option c\n");  
            break;  
          case 'd':  
            printf("option d\n");  
            break;  
          case 'e':  
            printf("option e\n");  
            break;  
          default:  
            printf("other option:%c\n",ch);  
        }  
        printf("optopt+%c\n",optopt);  
      }  

    }  

在終端執行以下啓動命令:

./a.out -a1234 -b432 -c -d  

輸出如下:

    optind:2  
    optarg:1234  
    ch:a  
    option a:'1234'  
    optopt+  
    optind:3  
    optarg:432  
    ch:b  
    option b:'432'  
    optopt+  
    optind:4  
    optarg:(null)  
    ch:c  
    option c  
    optopt+  
    optind:5  
    optarg:(null)  
    ch:d  
    option d  
    optopt+  

main(int argc,char *argv[])中的argc是一個整型,argv是一個指針數組,argc記錄argv的大小。上面的例子中。

  • argc=5;
  • argv[0]=./a.out
  • argv[1]=-a1234
  • argv[2]=-b432
  • argv[3]=-c
  • argv[4]=-d

getopt函數原型:

getopt(int argc,char *const argv[],const char *optstring)  
  • optstring是一段自己規定的選項串,例如本例中的”a:b::cde”,表示可以有,-a,-b,-c,-d,-e這幾個參數
  • “:”表示該選項必須帶有額外的參數,全域變量optarg會指向此額外參數,“::”標識該額外的參數可選(有些Uinx可能不支持“::”)
  • 全域變量optind指示下一個要讀取的參數在argv中的位置
  • 如果getopt()找不到符合的參數則會印出錯信息,並將全域變量optopt設爲“?”字符
  • 如果不希望getopt()印出錯信息,則只要將全域變量opterr設爲0即可

判斷文件的訪問權限


頭文件:

    int _access( const char *path, int mode );  

    int _waccess(  const wchar_t *path, int mode );  
  • 參數:
    path 文件或目錄路徑
    ode 訪問權限設定
  • 返回值:
    如果文件具有指定的訪問權限,則函數返回 0
    如果文件不存在或者不能訪問指定的權限,則返回-1

  • 當path爲文件時,_access函數判斷文件是否存在,並判斷文件是否可以用mode值指定的模式進行訪問

  • 當path爲目錄時,_access只判斷指定的目錄是否存在

mode的值和含義:

  • 00 檢查文件是否存在

  • 02 寫權限

  • 04 讀權限

  • 06 讀寫權限

localtime()函數


鏈接:http://blog.csdn.net/shellching/article/details/8114266

SetConsoleCtrlHandler控制檯處理函數


鏈接:http://andylin02.iteye.com/blog/661431

inline函數


在函數聲明或定義中函數返回類型前加上關鍵字inline即把min()指定爲內聯。

inline int min(int first, int secend) {/****/};

inline 函數對編譯器而言必須是可見的,以便它能夠在調用點內展開該函數。與非inline函數不同的是,inline函數必須在調用該函數的每個文本文件中定義。當然,對於同一程序的不同文件,如果inline函數出現的話,其定義必須相同。對於由兩個文件compute.C和draw.C構成的程序來說,程序員不能定義這樣的min()函數,它在compute.C中指一件事情,而在draw.C中指另外一件事情。如果兩個定義不相同,程序將會有未定義的行爲:
爲保證不會發生這樣的事情,建議把inline函數的定義放到頭文件中。在每個調用該inline函數的文件中包含該頭文件。這種方法保證對每個inline函數只有一個定義,且程序員無需複製代碼,並且不可能在程序的生命期中引起無意的不匹配的事情
inline 說明這個函數是內聯的,在編譯過程中內聯函數會直接被源代碼替換,提高執行效率 如果類中的某個函數會被調用很多次或者放在循環中,那麼建議將這個函數聲明爲內聯,可以提高程序的運行效率

CreateDirectory創建文件目錄


鏈接:http://blog.sina.com.cn/s/blog_618a89940101nl41.html

整形字符轉換

strtoul函數

將字符串轉換成無符號長整型數,類似的函數還有atof,atoi,atol,strtod,strtol
原型:

unsigned long strtoul(const char *nptr,char **endptr,int base);
  • [說明] strtoul()會將參數nptr字符串根據參數base來轉換成無符號的長整型數。參數base範圍從2至36,或0。參數base代表採用的進制方式,如base值爲10則採用10進制,若base值爲16則採用16進制數等。當base值爲0時會根據情況選擇用哪種進制:如果第一個字符是’0’,就判斷第二字符如果是‘x’則用16進制,否則用8進制;第一個字符不是‘0’,則用10進制。一開始strtoul()會掃描參數nptr字符串,跳過前面的空格字符串,直到遇上數字或正負符號纔開始做轉換,再遇到非數字或字符串結束時(”)結束轉換,並將結果返回。若參數endptr不爲NULL,則會將遇到不合條件而終止的nptr中的字符指針由endptr返回。
  • [返回值] 返回轉換後的長整型數,否則返回ERANGE並將錯誤代碼存入errno中

_ultoa函數

轉換一個無符號長整型數爲字符串
原型:

char *ultoa(unsigned long value, char *string, int radix);

示例:

#include
#include
int main( void )
{
unsigned long lnumber = 3123456789L;
char string[25];
ultoa(lnumber,string,10);
printf("string = %s unsigned long = %lu\n",string,lnumber);
return 0;
}

將lnumber轉換成字符型,然後添加到字符數組string中

進程或線程相關函數

SetPriorityClass

設置進程的優先級
函數原型:

BOOL WINAPI SetPriorityClass(
  _In_ HANDLE hProcess,
  _In_ DWORD  dwPriorityClass
);

【參數】

  • hProcess
    進程句柄,可以通過GetCurrentProcess等函數獲取
  • dwPriorityClass
    優先級級別,如:ABOVE_NORMAL_PRIORITY_CLASS(在普通優先級之上)

獲取當前進程或線程句柄或ID

函數如下:

  • {返回當前線程的虛擬句柄}
    GetCurrentThread: THandle;
  • {返回當前線程 ID}
    GetCurrentThreadId: DWORD;
  • {返回當前進程的虛擬句柄}
    GetCurrentProcess: THandle;
  • {返回當前進程 ID}
    GetCurrentProcessId: DWORD;

詳見鏈接:(http://www.cnblogs.com/del/archive/2008/03/10/1098311.html)

CreateToolhelp32Snapshot進程快照

獲取進程信息爲指定的進程、進程使用的堆[HEAP]、模塊[MODULE]、線程建立一個快照。
原型:

HANDLE WINAPI CreateToolhelp32Snapshot(
  DWORD dwFlags, //用來指定“快照”中需要返回的對象,可以是TH32CS_SNAPPROCESS等
  DWORD th32ProcessID //一個進程ID號,用來指定要獲取哪一個進程的快照,當取系統進程列表或獲取當前進程快照時可以設爲0
  );

【參數】

1、dwFlags
指定快照中包含的系統內容,這個參數能夠使用下列數值(常量)中的一個或多個:

  • TH32CS_INHERIT - 聲明快照句柄是可繼承的;
  • TH32CS_SNAPALL - 在快照中包含系統中所有的進程和線程;
  • TH32CS_SNAPHEAPLIST - 在快照中包含在th32ProcessID中指定的進程的所有的堆;
  • TH32CS_SNAPMODULE - 在快照中包含在th32ProcessID中指定的進程的所有的模塊;
  • TH32CS_SNAPPROCESS - 在快照中包含系統中所有的進程; 
  • TH32CS_SNAPTHREAD -在快照中包含系統中所有的線程;

2、th32ProcessID
指定將要快照的進程ID。如果該參數爲0表示快照當前進程。該參數只有在設置了TH32CS_SNAPHEAPLIST或者TH32CS_SNAPMODULE後纔有效,在其他情況下該參數被忽略,所有的進程都會被快照;

返回值】
  調用成功,返回快照的句柄,調用失敗,返回INVALID_HANDLE_VALUE

獲取進程中的線程或線程枚舉

進程爲線程提供生存的空間,線程爲進程的存在提供了時間,沒有線程的存在進程沒有存在的意義,一個進程中可以同時具有多個線程,但必須有一個線程,進程生成時創建的第一個線程被稱之爲主線程,它可以創建子線程,子線程還可以創建孫線程。

通過函數CreateToolhelp32Snapshot創建進程快照;
通過函數Thread32First獲取第一個線程信息;
通過函數Thread32Next獲取下一個線程信息;
原型:

BOOL WINAPI Thread32First(HANDLE hSnapshot,  LPTHREADENTRY32 lpt2)

BOOL WINAPI Thread32Next(HANDLE hSnapshot, LPTHREADENTRY32 lpte);

OpenThread打開線程

用於打開一個現有線程對象。
原型:

HANDLE WINAPI OpenThread(
    _In_ DWORD dwDesiredAccess,
    _In_ BOOL  bInheritHandle,
    _In_ DWORD dwThreadId 
);

【參數】

  • dwDesiredAccess 線程對象的訪問。此訪問權限檢查線程的安全描述符。這個參數可以是一個或多個線程訪問權限;
  • bInheritHandle 如果這個值是true的,這個進程將繼承該句柄的進程。否則,進程不繼承此句柄;
  • dwThreadId 要打開的線程的標識符;

SetThreadAffinityMask 指定線程的運行CPU

該函數實現爲各個線程設置親緣性屏蔽,即爲線程指定運行的CPU
原型:

 DWORD_PTR  SetThreadAffinityMask  ( 
      HANDLE     hThread,   //  handle  to  thread 
      DWORD_PTR  dwThreadAffinityMask   //  thread  affinity  mask 
  ); 

【參數】

  • hThread 用於指明要限制的線程標識;
  • dwThreadAffinityMask 用於指明線程能夠在哪個CPU上運行,必須是進程的親緣性屏蔽的相應子集,例如,可能有一個包含4個線程的進程,它們在擁有4個CPU的計算機上運行。如果這些線程中的一個線程正在執行非常重要的操作,而你想增加某個CPU始終可供它使用的可能性,爲此你對其他3個線程進行了限制,使它們不能在CPU 0上運行,而只能在CPU 1、2和3上運行。因此,若要將3個線程限制到CPU 1、2和3上去運行,可以這樣操作:
  //線程0只能在cpu  0上運行 
  SetThreadAffinityMask(hThread0,0x00000001); 
  //線程1,2,3只能在cpu  1,2,3上運行 
  SetThreadAffinityMask(hThread1,0x0000000E); 
  SetThreadAffinityMask(hThread2,0x0000000E); 
  SetThreadAffinityMask(hThread3,0x0000000E); 

【返回值】
線程的前一個親緣性屏蔽

時間函數

  • 1 得到當前UTC時間
void GetSystemTime(LPSYSTEMTIME lpSystemTime);
  • 2 得到當地時間
void GetLocalTime(LPSYSTEMTIME lpSystemTime);
  • 3 SYSTEMTIME轉成FILETIME
BOOL SystemTimeToFileTime(

    const SYSTEMTIME* lpSystemTime,

    LPFILETIME lpFileTime

);
  • 4 FILETIME轉成SYSTEMTIME
BOOL FileTimeToSystemTime(

    const FILETIME* lpFileTime,

    LPSYSTEMTIME lpSystemTime

);
  • 5 當地時間轉成UTC時間
BOOL LocalFileTimeToFileTime(

    const FILETIME* lpLocalFileTime,

    LPFILETIME lpFileTime

);
  • 6 UTC時間轉成當地時間
BOOL FileTimeToLocalFileTime(

       const FILETIME* lpFileTime,

       LPFILETIME lpLocalFileTime

);
  • 7 獲取系統運行時間
CopyBOOL WINAPI GetSystemTimes(
  __out_opt  LPFILETIME lpIdleTime,   //空閒時間
  __out_opt  LPFILETIME lpKernelTime, //內核時間
  __out_opt  LPFILETIME lpUserTime    //用戶時間
);

【CUP利用率計算方法】
總時間=內核時間+用戶時間;
cpu利用率=(總時間-空閒時間)/總時間

獲取系統內存信息

函數GlobalMemoryStatusEx和GlobalMemoryStatus。
當系統內存大於4G時,只能使用函數GlobalMemoryStatusEx獲取內存信息。

函數原型:

BOOL WINAPI  GlobalMemoryStatusEx(LPMEMORYSTATUS  lpBuffer)

參數:是一個指向MEMORYSTATUSEX結構體的指針

MEMORYSTATUSEX結構如下:

 typedef struct _MEMORYSTATUSEX {

  DWORD     dwLength; //本結構長度

  DWORD     dwMemoryLoad; //已用內存百分比

  DWORDLONG ullTotalPhys; //物理內存總量

  DWORDLONG ullAvailPhys; //可用物理內存

  DWORDLONG ullTotalPageFile; //頁交換文件最多能放的字節數

  DWORDLONG ullAvailPageFile; //頁交換文件中尚未分配給進程的字節數

  DWORDLONG ullTotalVirtual; //用戶區總的虛擬地址空間

  DWORDLONG ullAvailVirtual; //用戶區當前可用的虛擬地址空間

  DWORDLONG ullAvailExtendedVirtual; //保留值,設爲0

} MEMORYSTATUSEX, *LPMEMORYSTATUSEX;

ullAvailVirtual這個值是這個結構中唯一一個與該進程有關的成員,所有的其他成員
都適用於整個系統,爲了計算這個值GlobalMemoryStatus會把調用進程的地址空間中所有的閒置區域都加起來。

WSAStartup和WSACleanup

通常這兩個函數要搭配使用。
WSAStartup的功能是初始化Windows socket DLL,WSACleanup是來解除與Socket庫的綁定並且釋放Socket庫所佔用的系統資源。
函數原型:

int PASCAL FAR WSAStartup( WORD wVersionRequested,  LPWSADATA lpWSAData );

【參數】

  1. wVersionRequested 欲使用的 Windows Sockets API 版本,高位字節指出副版本(修正)號,低位字節指明主版本號;
  2. lpWSAData 指向WSADATA數據結構的指針,用來接收Windows Sockets實現的細節;
    【返回值】
    成功 ——0
    失敗——-WSASYSNOTREADY / WSAVERNOTSUPPORTED / WSAEINVAL

InterlockedIncrement16和InterLockedDecrement

屬於互鎖函數,用在同一進程內,需要對共享的一個變量做加法或減法的時候,
防止其他線程訪問這個變量,是實現線程同步的一種辦法

InterlockedIncrement函數可以實現對變量的同步操作,當多個線程或進程操作同一個變量時,此函數可以保證對操作的變量同步,對變量進行加法操作。

如:
變量 Long value =0;
  正常情況下的加減操作:value+=1;
  1:系統從Value的空間取出值,並動態生成一個空間來存儲取出來的值;
  2:將取出來的值和1作加法,並且將和放回Value的空間覆蓋掉原值。加法結束。
  如果此時有兩個Thread ,分別記作threadA,threadB;
  1:threadA將Value從存儲空間取出,爲0;
  2:threadB將Value從存儲空間取出,爲0;
  3:threadA將取出來的值和1作加法,並且將和放回Value的空間覆蓋掉原值。加法結束,Value=1。
  4:threadB將取出來的值和1作加法,並且將和放回Value的空間覆蓋掉原值。加法結束,Value=1。
  最後Value =1 ,而正確應該是2;這就是問題的在,InterLockedIncrement 能夠保證在一個線程訪問變量時其它線程不能訪問。
  用於增減變量的並不是常用的Inc/Dec過程,而是用了InterlockedIncrement/InterlockedDecrement這一對過程,它們實現的功能完全一樣,都是對變量加一或減一。但它們有一個最大的區別,那就是InterlockedIncrement/InterlockedDecrement是線程安全的。即它們在多線程下能保證執行結果正確,而Inc/Dec不能

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章