首页
社区
课程
招聘
[原创]windows API汇总
发表于: 2022-9-9 18:44 6403

[原创]windows API汇总

2022-9-9 18:44
6403

一、字符串操作

备注:关于字符串操作
_s结尾的是:具备检测缓冲区溢出检测功能,缓冲区溢出时debug版本程序会报错,release直接崩溃
带n的:具备缓冲区溢出时,自动截断功能。
1 _tcsncpy 拷贝n个字符串
2 _tcscpy_s 拷贝字符串
3 _tcscmp 字符串比较
4 _tcsicmp 忽略大小写字符串比较
5 _tcsncmp 字符串比较前n个字符
6 _tcslen 获取字符串长度
7 _tcscat_s 字符串拼接
8 _tcschr 查找字符串中某个字符第一次出现的位置
9 _tcsrchr 查找字符串中某个字符最后一次出现的位置
10 _tcsstr 字符串1在字符串2中首次出现的位置,未出现返回NULL值;
11 _tcsrstr 字符串1在字符串2中最后出现的位置,未出现返回NULL值;
12 _tcstok_s 按标记将字符串拆分
13 _stprintf_s 格式化字符串
_stprintf_s这个函数不推荐用,可以用_sntprintf_s
14 _stscanf_s 分割格式化字符串
15 _sntprintf_s 强烈推荐格式化字符串(以后字符串格式化只使用这个函数),防止缓冲区溢出的最好的函数。

1
2
3
使用方法:
    TCHAR szLog[MAX_PATH] = {0};   
    _sntprintf_s(szLog, MAX_PATH, MAX_PATH - 1, _T("GetClassName=%s\n"), szBuff);

16 _tcslwr 字符串转小写

1
2
3
使用方法:
    wstring wstrSql = L"zHONGguoREN";
    wstrSql = _wcslwr((WCHAR*)wstrSql.c_str());

17 _tcslwr_s 字符串转小写安全版本

1
2
TCHAR name[] = L"SalAnlei";           
_tcslwr_s(name, _tcslen(name) + 1);

18 _tcsupr 字符串转大写
19 _tcsupr_s 字符串转大写安全版本
20 string.find() 查找子串
21 int k=str1.find_first_of(str2); k返回的值是"str2字符中任何一个字符"首次在str1中出现的位置,和find有本质区别
22 int k=str1.find_last_of(str2); k返回的值是"str2字符中任何一个字符"首次在str1尾部中出现的位置,和find有本质区别
23 strncpy
注意:strncpy不会自动追加'\0',如果使用strncpy一定要手动追加'\0'

1
2
3
正确用法:
    strncpy(dst, src, dst_size-1);
    dst[dst_size-1] = '\0'; /* Always do this to be safe! */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int main()
{
    //1、dest中没有被初始化为0,部分拷贝,strncpy不会自动追加\0
    char dest[20] = {0};
    char src[] = "123456";
 
    memset(dest, 'a', sizeof(dest));//设置dest内容为'a'
    strncpy(dest, src, 2);//部分拷贝,strncpy不会自动追加\0
    dest[2] = '\0';//这句非常重要!!!!,否则字符串没有结束标志
 
    //2、src2字符串的长度大于sizeof(dest2),strncpy不会自动追加\0
    char dest2[20] = { 0 };
    char src2[] = "01234567890123456789123456";
    memset(dest2, 'b', sizeof(dest2));
    strncpy(dest2, src2, sizeof(dest2));
    dest2[sizeof(dest2) - 1] = '\0';//这句非常重要!!!!否则字符串没有结束标志
    //3、推荐的写法
    char dest3[20];
    char src3[] = "123456789";
    memset(dest3, 0, sizeof(dest3));//先把dest3初始化为0
    strncpy(dest3, src, sizeof(dest3) - 1);
}

24 strncpy_s

1
2
3
4
5
6
7
8
9
int main()
{
   char src[] = "1234567890";
   char dst[5];
   errno_t err = strncpy_s(dst, _countof(dst), src, _TRUNCATE);
   if ( err == STRUNCATE )
      printf( "truncation occurred!\n" );
   printf( "'%s'\n", dst );
}

25 int snprintf(charstr, size_t size,constcharformat, ...);
备注:这个函数是安全的,推荐使用,而snprintf是不安全的,千万不要用(前面仅仅比snprintf多个
snprintf与_snprintf的区别是_snprintf不会末尾置0就不说了)
函数说明:
(1) 如果格式化后的字符串长度 < size,则将此字符串全部复制到str中,并给其后添加一个字符串结束符('\0');
(2) 如果格式化后的字符串长度 >= size,则只将其中的(size-1)个字符复制到str中,并给其后添加一个字符串结束符('\0'),返回值为欲写入的字符串长度。
函数返回值:
若成功则返回欲写入的字符串长度,若出错则返回负值。返回值并不是真正写入字符串的大小。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main() 
  char buf[10] = ""; 
  char src[30] = "hello world! hello world!"
  int len = snprintf(buf, sizeof(buf), "%s", src); 
  printf("return len=%d\n", len); 
  if(len>sizeof(buf)-1
  
    printf("[Error] Source string length is %d. The buf size %d is not enough. Copy incomplete!\n", len, sizeof(buf)); 
  }else
    printf("buf=%s, bufLen=%d\n", buf, strlen(buf)); 
  
  return 0
}

26 sprintf格式
%d 十进制有符号整数
%u 十进制无符号整数
%f 浮点数
%s 字符串
%c 单个字符
%p 指针的值
%e 指数形式的浮点数
%x, %X 无符号以十六进制表示的整数
%o 无符号以八进制表示的整数
%g 把输出的值按照 %e 或者 %f 类型中输出长度较小的方式输出
%p 输出地址符
%lu 32位无符号整数
%llu 64位无符号整数
%2f是把float的所有位数输出2位,包括小数点,如果不组2位,补0,如果超过2位,按照实际输出
%.2f是float后的小数只输出两位。
%d=int
%ld= long
%lld=long long
27 、sscanf函数是不安全的函数,格式和参数不符,容易造成缓冲区溢出
备注:X代表16进制、04代表不足补0
格式%04X :需要类型“unsigned int ”的参数
格式%hX :需要类型“unsigned short
”的参数
格式%02hhX :需要类型“unsigned char *”的参数

 

28、 STL string模仿CString的Format函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template<typename ... Args>
string string_format(const string& format, Args ... args)
{
    size_t size = 1 + snprintf(nullptr, 0, format.c_str(), args ...);  // Extra space for \0
     unique_ptr<char[]> buf(new char[size]);
    //char bytes[size];
    snprintf(buf.get(), size, format.c_str(), args ...);
    return string(buf.get());
}
int main() {
    //test the function here
    cout << string_format("name=%s, id=%d", "sanganlei", 202412);
    //<test>
    return 0;
}

29、 STL string模仿CString的Format函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// CMakeProject1.cpp: 定义应用程序的入口点。
//
 
 
#include <iostream>
#include <stdio.h>
#include <memory>
#include <stdarg.h>
 
using namespace std;
 
 
//#ifndef _UNICODE
 
template<typename ... Args>
string string_format2(const string& format, Args ... args)
{
    if (format.empty()) {
        return FT("");
    }
    size_t nLen = 1 + snprintf(NULL, 0, format.c_str(), args ...);  // Extra space for \0
    char* strBuffer = new(std::nothrow) char[nLen];
    if (!strBuffer) {
        return "";
    }
    snprintf(strBuffer, nLen, format.c_str(), args ...);
 
    string strRlst = strBuffer;
    delete[]  strBuffer;
    strBuffer = NULL;
    return strRlst;
}
 
 
template<typename ... Args>
wstring string_format2(const wchar_t* format, Args ... args)
{
    if (!format) {
        return L"";
    }
 
    va_list vlArgs = NULL;
    va_start(vlArgs, format);
    size_t nLen = _vscwprintf(format, vlArgs) + 1;
    wchar_t* strBuffer = new wchar_t[nLen];
    _vsnwprintf_s(strBuffer, nLen, nLen, format, vlArgs);
    va_end(vlArgs);
 
    wstring strRlst = strBuffer;
    delete[] strBuffer;
    strBuffer = NULL;
    return strRlst;
}

30、 windows版本outputdebugStringEx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <windows.h>
#include <stdio.h>
#include "OutputDebugEx.h"
 
void OutputDebugStringEx(const wchar_t *strOutputString, ...)
{
    va_list vlArgs = NULL;
    va_start(vlArgs, strOutputString);
    size_t nLen = _vscwprintf(strOutputString, vlArgs) + 1;
    wchar_t *strBuffer = new wchar_t[nLen];
    _vsnwprintf_s(strBuffer, nLen, nLen, strOutputString, vlArgs);
    va_end(vlArgs);
    OutputDebugStringW(strBuffer);
    delete[] strBuffer;
}
 
void OutputDebugStringEx(const char *strOutputString, ...)
{
    va_list vlArgs = NULL;
    va_start(vlArgs, strOutputString);
    size_t nLen = _vscprintf(strOutputString, vlArgs) + 1;
    char *strBuffer = new char[nLen];
    _vsnprintf_s(strBuffer, nLen, nLen, strOutputString, vlArgs);
    va_end(vlArgs);
    OutputDebugStringA(strBuffer);
    delete[] strBuffer;
}

二、内存操作

1、memcpy_s 内存拷贝
2、new和delete、new[]和delete[]要配对使用,否则会造成堆破坏和内存泄漏

三、文件操作

1、fstream、ifstream和ofstream构造函数打开文件
构造函数的主要功能是打开文件,内部调用了fopen函数,和单独调用fopen效果一样。
图片描述
2、fstream构造函数打开文件方式
图片描述
a) fstream的std::ios::app打开文件
在每次写操作之前,流指针会定位到文件末尾,只能在文件末尾追加内容。
无论您为写入指针设置什么位置, ios::app您都将始终在最后写入。
打开文件时,若文件不存在,会创建新文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
int main()
{
 
    //1、在每次写文件时,在文件末尾追加内容(打开文件后tellg和tellp定位到文件末尾,但每次写入时,定位到文件结尾)
    //ios::app打开时,若文件不存在,则会创建文件
    long lread, lwrite;
    long lread2, lwrite2;
    fstream fs("1.txt", std::ios::in | std::ios::out | std::ios::app);
    if (fs) {
        cout << "file exist" << endl;
        lread = fs.tellg();//获取读指针
        lwrite = fs.tellp();//获取写指针
        fs.write("sanganlei", sizeof("sanganlei"));
        lread2 = fs.tellg();
        lwrite2 = fs.tellp();
 
        fs.seekp(SEEK_SET);
        lread2 = fs.tellg();
        lwrite2 = fs.tellp();
        fs.write("hello", sizeof("hello"));
 
        fs.close();
    }
    else {
        cout << "file not exist" << endl;
    }
}

b)fstream的std::ios::trunc打开文件
打开文件时,删除文件原有内容。
打开文件时,若文件不存在,会创建新文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int main()
{
    //2、打开文件后删除原有内容((打开文件后tellg和tellp定位到开头))
    //ios::trunc打开时,若文件不存在,则会创建文件
    long lread, lwrite;
    long lread2, lwrite2;
    fstream fs("1.txt", std::ios::in | std::ios::out | std::ios::trunc);
    if (fs) {
        cout << "file exist" << endl;
        lread = fs.tellg();
        lwrite = fs.tellp();
        fs.write("sanganlei", sizeof("sanganlei"));
        lread2 = fs.tellg();
        lwrite2 = fs.tellp();
        fs.close();
    }
    else {
        cout << "file not exist" << endl;
    }
}

c)fstream的std::ios::ate打开文件
每次打开文件后,读写指针定位到文件末尾。
打开文件时,若文件不存在,不会创建新文件。
ios::ate好处是可以在文件中自由搜索

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int main()
{
    //3、每次打开文件后,读写指针定位到文件末尾(打开文件后tellg和tellp定位到文件末尾)
    //ios::ate打开时,若文件不存在,不会创建文件
    long lread, lwrite;
    long lread2, lwrite2;
    fstream fs("1.txt", std::ios::in | std::ios::out | std::ios::ate);
    if (fs) {
        cout << "file exist" << endl;
        lread = fs.tellg();
        lwrite = fs.tellp();
        fs.write("sanganlei", sizeof("sanganlei"));
        lread2 = fs.tellg();
        lwrite2 = fs.tellp();
        fs.close();
    }
    else {
        cout << "file not exist" << endl;
    }
}

d)文件存在就读取内容,不存在就创建文件ifstream和ofstream联合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int main() {
    string fcstrConfigPath;
    fcstrConfigPath = ("D:\\111config.json");
    std::ifstream fIn(fcstrConfigPath.c_str()); //fin用来判断文件是否存在和读取文件内容
 
    if (!fIn.good()) {//文件不存在
        std::ofstream fOut(fcstrConfigPath.c_str(), std::ios::out | std::ios::binary);//创建文件并打开
        if (!fOut.is_open()) {//判断文件是否打开
            return -1;
        }
        std::string strTempJson = "Hello";
        fOut.write(strTempJson.c_str(), strTempJson.length());//写入内容
        fOut.close();
    }
    else {//存在,读取文件内容
        std::string strJson((std::istreambuf_iterator<char>(fIn)), std::istreambuf_iterator<char>());//读取文件内容
        fIn.close();//关闭文件
    }
 
    return 0;
}

3 std::ios::rdstate含义
图片描述

 

4 _tfopen 打开文件
r 打开(OPEN)只读文件,该文件必须存在。
r+ 打开(OPEN)可读写的文件,该文件必须存在。
w 打开(OPEN)只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则新建该文件。
w+ 打开(OPEN)可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则新建该文件。
a 以附加的方式打开(OPEN)只写文件。若文件不存在,则会新建该文件,假如文件存在,输入的数据会被加到文件尾,即文件原先的内容会被保留。
a+ 以附加方式打开(OPEN)可读写的文件。若文件不存在,则会新建该文件,假如文件存在,输入的数据会被加到文件尾后,即文件原先的内容会被保留。
上述的形态字符串都可再加1个b字符,如rb、w+b或ab+等组合,加入b 字符用来告知函数库打开(OPEN)的文件为二进制文件,而非纯文字文件
5 _fclose 关闭文件
6 _size_t fread(void buffer, size_t size, size_t count, FILE stream) 读文件
返回实际读取的单元个数。如果小于count,则可能文件结束或读取出错;可以用ferror()检测是否读取出错,
用feof()函数检测是否到达文件结尾。如果size或count为0,则返回0。
7 _size_t fwrite(void buffer, size_t size, size_t count, FILE stream); 写文件
返回成功写入的单元个数。如果小于count,则说明发生了错误,文件流错误标志位将被设置,随后可以通过ferror()函数判断。
如果 size 或 count 的值为 0,则返回值为 0
8 _ftprintf 文件格式化写
9 _ftscanf 文件格式化读
10 _fgetc 文件中读取一个字符
11 _fputc 将一指定字符写入文件流中
12 _fgets 由文件中读取一字符串,直到出现换行字符、读到文件尾或是已读了size-1个字符为止,最后会加上NULL作为字符串结束
13 _fputs 将一指定的字符串写入文件内,若成功则返回写出的字符个数,返回EOF则表示有错误发生
14 _fflush 缓冲区到文件
15 _fseek(pf,offset,origin) pf:文件指针,offset:以字节为单位的位移量,origin:是起始点,用来指定位移量是以哪个位置为基准的.
16 _feof 判断文件结束函数
17 _ftell 当前位置指针相对于文件开头的字节数
18 _rewind 重设文件流的读写位置为文件开头
19 _ferror 测试给定流 stream 的错误标识符。如果设置了与流关联的错误标识符,该函数返回一个非零值,否则返回一个零值。
20 _void clearerr(FILE *stream) 清除给定流 stream 的文件结束和错误标识符。

 

21 _PathFindFileName 根据文件路径获取文件名
Path before calling "PathFindFileName ": C:\www.txt
Path after calling "PathFindFileName ": www.txt
22 _PathRemoveFileSpec 根据文件路径获取文件所在目录
Path before calling "PathRemoveFileSpec": C:\TEST\sample.txt
Path after calling "PathRemoveFileSpec": C:\TEST
23 _PathRemoveArgs 移除路径中的参数
Path before calling "PathRemoveArgs": c:\a\b\FileA Arg1 Arg2
Path before calling "PathRemoveArgs": c:\a\b\FileA
24 _PathRemoveBackslash 路径尾部去掉反斜杠
Path before calling "PathRemoveBackslash": c:\a\b\File\
Path after calling "PathRemoveBackslash": c:\a\b\File
25 _PathAddBackslash 路径尾部增加反斜杠
Path before calling "PathAddBackslash": c:\a\b\File
Path after calling "PathAddBackslash": c:\a\b\File\
26 _PathRemoveBlanks删除路径中的空格
Path before calling "PathRemoveBlanks": c:\TEST\File1\File2
Path after calling "PathRemoveBlanks": c:\TEST\File1\File2
27 _PathAddExtension增加扩展名
Path before calling "PathAddExtension": file
Path after calling "PathAddExtension": file.txt
28 _PathRemoveExtension去掉扩展名
Path before calling "PathRemoveExtension": C:\TEST\sample.txt
Path after calling "PathRemoveExtension": C:\TEST\sample
29 _PathRenameExtension重命名扩展名
Path before calling "PathRenameExtension": C:\TEST\sample.txt
Path after calling "PathRenameExtension": C:\TEST\sample.doc
30 _PathUnquoteSpaces 去掉路径的引号
Path before calling "PathUnquoteSpaces": "C:\path1\path2"
Path after calling "PathUnquoteSpaces": C:\path1\path2
31 _PathQuoteSpaces 路径加引号
Path before calling "PathQuoteSpaces ": C:\sample_one\sample two
Path after calling "PathQuoteSpaces ": "C:\sample_one\sample two"
32 _PathStripPath 去掉路径,只留下文件名
Path before calling "PathStripPath ": c:\dir1\file.txt
Path after calling "PathStripPath ": file.txt
33 _PathCompactPath 路径压缩
The un-truncated path is C:\path1\path2\sample.txt
The truncated path at 125 pixels is : C:\pa...\sample.txt
34 _PathCompactPathEx 路径压缩
Path before calling "PathCompactPathEx ": C:\path1\path2\sample.txt
Path after calling "PathCompactPathEx ": ...\sa...
35 _PathFindExtension 查找路径中的扩展名
Path before calling "PathFindExtension ": C:\www.txt
Path after calling "PathFindExtension ": .txt
36 _PathFindNextComponent 返回第一个反斜杠后面的内容
Search a path for the next path component after the root c:\a\b\File
Return the next path component: "a\b\File"
37 _PathMakePretty 转换为小写
The content of the unconverted path is : C:\TEST\FILE
The content of the converted path is : C:\test\file


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2022-11-22 20:59 被sanganlei编辑 ,原因:
收藏
免费 1
支持
分享
最新回复 (2)
雪    币: 6566
活跃值: (4526)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
2
收藏备用
2022-9-9 19:04
0
雪    币: 4383
活跃值: (3393)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
辛苦
2022-9-10 08:24
0
游客
登录 | 注册 方可回帖
返回
//