一、字符串操作
备注:关于字符串操作
_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: 定义应用程序的入口点。
/ /
using namespace std;
/ /
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 | 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编辑
,原因: