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 );
【參數】
- wVersionRequested 欲使用的 Windows Sockets API 版本,高位字節指出副版本(修正)號,低位字節指明主版本號;
- 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不能