C++ 常用&生僻函数小记

来源:互联网 发布:windows hook框架 编辑:程序博客网 时间:2024/06/05 16:52

  • string类
    • find函数
    • find_first_of
    • substr函数
  • 动态载入DLL相关函数
    • LoadLibrary函数
    • GetProcAddress函数
    • FreeLibrary函数
  • getopt函数
  • 判断文件的访问权限
  • localtime函数
  • SetConsoleCtrlHandler控制台处理函数
  • inline函数
  • CreateDirectory创建文件目录
  • 整形字符转换
    • strtoul函数
    • _ultoa函数
  • 进程或线程相关函数
    • SetPriorityClass
    • 获取当前进程或线程句柄或ID
    • CreateToolhelp32Snapshot进程快照
    • 获取进程中的线程或线程枚举
    • OpenThread打开线程
    • SetThreadAffinityMask 指定线程的运行CPU
  • 时间函数
  • 获取系统内存信息
  • WSAStartup和WSACleanup
  • InterlockedIncrement16和InterLockedDecrement

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

0 0
原创粉丝点击