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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值