实用程序
一篇关于简单但常用的实用函数的文章。
引言
我遇到过无数次的情况,常规使用的实用函数根本不可用,开发人员不得不反复编写和重写它们。这篇文章将尝试提供一系列静态实用函数,将它们打包到一个 C++ 类中,这些函数是我多年来收集的,并在 50 多个各种规模的项目中反复使用过。
这些函数既不是软件工程的突破,也不是最优化、精简和强大的实现。它们仅仅是我在众多项目中收集的最常用的实用函数,以最方便的方式打包,为我和与我一起工作的开发人员节省了数百小时。
该类及其函数调用在多年来不断发展,以模仿一种在所有形式的 C++ 代码中最实用、最方便使用的东西,并且它们的性能通常足以满足大多数日常项目任务。
Using the Code
请遵循以下简单步骤,将代码用于您的 Microsoft Visual Studio C++ 项目
- 将 Util.h 和 Util.cpp 这两个文件添加到您的项目中。
- 在您打算使用这些实用函数的 *.cpp 文件的顶部添加
#include "Util.h"
这一行。 - 只需调用所需的静态函数,例如
CString strMyDocuments = CUtil::GetMyDocumentsDirectory().c_str()
。 - 请查看“Util.cpp”源文件以了解每个函数内部的工作原理,它们都经过了非常好的注释。
函数列表和描述
最适合文本文件的文件 I/O 函数
在许多项目中,唯一需要进行的磁盘操作是对大小从中等到小的文本文件的读/写操作,通常是以日志文件或存储简单用户数据的文件的形式;在其他项目中,需要报告或监视和记录任意大小的文件。无论哪种情况,这些函数都提供了一种简单的方法来完成项目所需的许多常规文件 I/O 任务。下面列出了一些函数,请查看头文件以了解所有可用函数。
static bool ReadFile(const _tstring& strFilePath, _tstring& strFileData)
static bool WriteFile(const _tstring& strFilePath, const _tstring& strFileData)
static long GetFileSize(const _tstring& strFilePath)
static __int64 GetFileSize64(const _tstring& strFilePath)
static bool IsFile(const _tstring& strFilePath)
字符串操作函数,返回成功替换的子字符串的数量
有时对字符串唯一需要做的事情就是查找某些内容并用其他内容替换它,并且要知道有多少个!这个函数只做这些,不多不少!还有其他几个类似的函数用于删除空格、垃圾字符和进行修剪。
它会将 strSource
中所有与 strFind
完全匹配的字符串替换为 strReplace
,并返回替换的次数。
static long FindReplace(
_tstring& strSource,
const _tstring& strFind,
const _tstring& strReplace)
字符串标记化函数
这些不是地球上最快或最复杂的字符串标记化器;事实上,远非如此!但是,它们对于大多数日常字符串标记化需求来说足够快,而且使用起来非常方便。
static long GetTokenCount(
const _tstring& strSource,
const _tstring& strDeliminator)
static _tstring GetToken(
const _tstring& strSource,
const _tstring& strDeliminator,
long lTokenIndex)
举个例子,需要从文件中读取数据,该文件只包含数字和换行符,您有兴趣获取所有数字,所以您可以这样做:
long lTokenIndex = 0;
long lTokenCount = (long) CUtil::GetTokenCount(strUserData, _T("\n"));
for(lTokenIndex = 0; lTokenIndex < lTokenCount; lTokenIndex++)
{
long lNumber = _tstol(CUtil::GetTokenCount(strUserData, _T("\n"),
lTokenIndex).c_str());
// Now you can do what ever you like with the number!
}
剪贴板:简单的文本复制/粘贴函数
static void Copy2Clipboard(const _tstring& strData)
static _tstring PasteFromClipboard()
数字到字符串转换器
在任何给定的项目中,都需要无数次将数字转换为字符串,从将文件大小和日期/时间放入日志文件中,到在 GUI 中报告复杂信息。这些函数提供了一种便捷的方式来完成此操作,只需在字符串 +=
语句的另一侧使用该函数即可。
第一个 Long2String
函数输出带有前导零的字符串;例如,Long2String(1234, 8);
将得到“00001234”。当您需要数字始终具有固定位数时,例如为具有连续编号的文件序列命名,这非常有用。
Double2String
函数输出小数点后指定位数的字符串,除非 lPrecision
未指定或设置为 0 或更低,在这种情况下,它不会截断;例如,Double2String(3.141592653);
将返回“3.141592653”,而 Double2String(3.141592653, 4);
将返回“3.1415”。
static _tstring Long2String(unsigned long lNumber, unsigned long lPrecision)
static _tstring Long2String(long long lNumber)
static _tstring Double2String(long double dNumber, unsigned long lPrecision = 0)
还有一些有用的函数用于查找有效数字的数量、四舍五入到特定小数位数以及检查一个数是否是 2 的幂。
static unsigned long NumberOfDigits(long lNumber)
static double Round(double dNumber2Round, unsigned long lPlaces)
static long Round(double dNumber2Round)
static bool IsPowerOf2(unsigned long iNumber)
字符串大小写转换器,大写转/从小写
static _tstring ToUpper(const _tstring& str)
static _tstring ToLower(const _tstring& str)
不区分大小写的比较,如果两个字符串在忽略大小写时相等,则返回 0
static int CompareNoCase(const _tstring& str1, const _tstring& str2)
系统时间检索
它返回一个以请求格式显示的当前系统日期/时间的字符串,这在日志记录或向用户显示日期/时间时非常有用。日期/时间格式修饰符的完整列表可在此处找到。
static _tstring GetSystemTime(
const _tstring& strDateFormat = _T("%A, %d/%m/%Y, %H:%M:%S - %Z"))
将给定的秒数转换为 hh:mm:ss,反之亦然
大多数时候,项目中进行的测量或进行的计算都以秒或毫秒为单位,这两者对于日志记录和向用户显示都毫无用处;最重要的是,如果用户需要输入时间值,对她来说,秒和毫秒通常是没有意义的。这些函数提供了简单的方法,可以在对用户有意义和对计算机有意义之间进行转换。
static _tstring GetTime(long lSeconds)
static long GetTime(const _tstring& strTime = _T("00:00:00"))
获取常用目录路径
常用的用户目录路径不是固定的!它们因计算机和用户的不同而异,这就是为什么这些函数在快速获取代码中需要的目录时非常有用。
请参阅这篇文章了解这些函数的用法详情。
static _tstring GetWorkingDirectory()
static _tstring GetProgramDirectory()
static _tstring GetProgramFilesDirectory()
static _tstring GetWindowsDirectory()
static _tstring GetSystemDirectory()
static _tstring GetMyDocumentsDirectory()
static _tstring GetMyMusicDirectory()
static _tstring GetMyPicturesDirectory()
static _tstring GetMyVideosDirectory()
static _tstring GetAppDataDirectory()
static _tstring GetLocalAppDataDirectory()
static _tstring GetDesktopDirectory()
static _tstring GetStartupDirectory()
将文件复制或剪切到另一个目录
此函数可以复制或剪切文件到目录,并在必要时创建目标目录的整个目录结构。
static bool CopyFile2Directory(
const _tstring& strSourceFilePath,
const _tstring& strDestinationDirectory,
bool bDeleteSource = false)
目录操作函数
请参阅这篇文章了解“GetFileList
”函数的更多详细信息。
// Get list of all files in the target directory
static void GetFileList(
const _tstring& strTargetDirectoryPath,
const _tstring& strWildCard,
bool bLookInSubdirectories,
vector<_tstring>& vecstrFileList)
// Create the entire directory path
static void MakeDirectory(const _tstring& strDirectoryPath);
// Delete the entire directory path, including all files and folders within
static void DeleteDirectory(const _tstring& strTargetDirectoryPath)
// Check whether the given path is a directory
static bool IsDirectory(const _tstring& strDirectoryPath)
// Add "\" to the end of a directory path, if not present
static _tstring AddDirectoryEnding(const _tstring& strDirectoryPath)
// Remove "\" from the end of a directory path, if present
static _tstring RemoveDirectoryEnding(const _tstring& strDirectoryPath)
// Get the name of the directory form a given directory path:
// e.g. C:\Program Files\XYZ, will return XYZ
static _tstring GetDirectoryName(const _tstring& strDirectoryPath)
// Get the directory from a file path
static _tstring GetFileDirectory(const _tstring& strFilePath)
// Get the previous directory from a given directory path
static _tstring GetRootDirectory(const _tstring& strDirectoryPath)
// Get the file name including/excluding the extension from a given file path
static _tstring GetFileName(const _tstring& strFilePath, bool bIncludeExtension = false)
// Get the file extension including/excluding the "." from a given file path
static _tstring GetFileExtension(const _tstring& strFilePath, bool bIncludeDot = false)
// Get the file prefix / suffix
static _tstring GetFileNamePrefix(const _tstring& strFilePath,
const _tstring& strDelimiter);
static _tstring GetFileNameSuffix(const _tstring& strFilePath,
const _tstring& strDelimiter);
字符串类型转换器,ANSI 转/自 Unicode
这些函数以干净方便的方式使用 Win32 API 函数 WideCharToMultiByte()
和 MultiByteToWideChar()
。您还会在这些函数中找到注释掉的代码,其中显示了其他转换方法,但这些注释掉的代码仅在 ASCII 字符集上可靠工作。
static wstring GetStringW(const string& strA)
static string GetStringA(const wstring& strW)
注册表
有时,唯一需要做的事情是将小块数据读/写入注册表,这不需要繁重而花哨的注册表编辑工具或类。
static _tstring GetRegistryInfo(
HKEY hKey,
const _tstring& strRegistryPath,
const _tstring& strValueName)
static bool SetRegistryInfo(
HKEY hkey,
const _tstring& strRegistryPath,
const _tstring& strValueName,
const _tstring& strValue)
使用示例:
_tstring strDirectory = GetRegistryInfo(
HKEY_LOCAL_MACHINE,
_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion"),
_T("ProgramFilesDir"));
bool bSuccess = SetRegistryInfo(
HKEY_LOCAL_MACHINE,
_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion"),
_T("ProgramFilesDir"),
_T("C:\\Program Files"));
互联网
此函数会运行默认的 Internet 浏览器应用程序来打开给定的 URL。
static HINSTANCE OpenURL(LPCTSTR strURL)
执行
使用此函数可以通过其默认应用程序打开文件,或使用一组输入参数运行可执行文件。
static bool Execute(
const _tstring& strFilePath,
const _tstring& strParameters = _T(""),
bool bShow = true,
bool bWait = false)
static bool Execute(
const _tstring& strCommandLine,
bool bShow = true,
bool bWait = false)
随机数生成器
在随机时间,出于随机原因,需要生成随机事物!
// Generate random string
static wstring GenerateRandomStringW(long lMaxLength,
bool bIncludeAlpha = true, bool bIncludeNumbers = true)
static string GenerateRandomStringA(long lMaxLength,
bool bIncludeAlpha = true, bool bIncludeNumbers = true)
// Generate random number between A & B
static float GetRandomNumber(float fA, float fB, float fGrain = 10.0f)
static double GetRandomNumber(double dA, double dB, double dGrain = 10.0)
// Simulate die roll in a bernoulli trial
static bool RollDice(double dProbability)
剖腹自杀
有时唯一的出路就是自我毁灭……此函数会简单地删除调用它的程序及其父目录。
static void SelfDestruct()
关注点
此处提供的代码适用于非托管 C++,兼容 Unicode 和 ANSI,并且部分代码可以在 Windows 以外的其他操作系统上使用。如果您觉得代码有用,请留下评论,这可能会让我的日子变得美好 :-)
历史
- V1.0 - 初始版本。
- V1.1 - 添加了几个新函数,并根据一些开发者的建议实现了一个更友好的界面。