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不能