各种小功能集一
十一、C/C++路径解析
头文件
std::string UtilsGetPath(const char *pszFilename);
std::string UtilsGetDirname(const char *pszFilename);
std::string UtilsGetFilename(const char *pszFullFilename);
std::string UtilsGetBasename(const char *pszFullFilename);
std::string UtilsGetExtension(const char *pszFullFilename);
源文件:使用案例如注释
/************************************************************************/
/* UtilsFindFilenameStart() */
/************************************************************************/
static int UtilsFindFilenameStart(const char * pszFilename)
{
size_t iFileStart = strlen(pszFilename);
for (;
iFileStart > 0
&& pszFilename[iFileStart - 1] != '/'
&& pszFilename[iFileStart - 1] != '\\';
iFileStart--) {
}
return static_cast<int>(iFileStart);
}
/************************************************************************/
/* UtilsGetPath() */
/************************************************************************/
/**
* Extract directory path portion of filename.
*
* Returns a string containing the directory path portion of the passed
* filename. If there is no path in the passed filename an empty string
* will be returned (not NULL).
*
* <pre>
* UtilsGetPath( "abc/def.xyz" ) == "abc"
* UtilsGetPath( "/abc/def/" ) == "/abc/def"
* UtilsGetPath( "/" ) == "/"
* UtilsGetPath( "/abc/def" ) == "/abc"
* UtilsGetPath( "abc" ) == ""
* </pre>
*
* @param pszFilename the filename potentially including a path.
*
* @return Path in an internal string which must not be freed. The string
* may be destroyed by the next CPL filename handling call. The returned
* will generally not contain a trailing path separator.
*/
std::string UtilsGetPath(const char *pszFilename)
{
const int iFileStart = UtilsFindFilenameStart(pszFilename);
if (iFileStart == 0) return "";
return std::string(pszFilename, pszFilename + iFileStart - 1);
}
/************************************************************************/
/* UtilsGetDirname() */
/************************************************************************/
/**
* Extract directory path portion of filename.
*
* Returns a string containing the directory path portion of the passed
* filename. If there is no path in the passed filename the dot will be
* returned. It is the only difference from UtilsGetPath().
*
* <pre>
* UtilsGetDirname( "abc/def.xyz" ) == "abc"
* UtilsGetDirname( "/abc/def/" ) == "/abc/def"
* UtilsGetDirname( "/" ) == "/"
* UtilsGetDirname( "/abc/def" ) == "/abc"
* UtilsGetDirname( "abc" ) == "."
* </pre>
*
* @param pszFilename the filename potentially including a path.
*
* @return Path in an internal string which must not be freed. The string
* may be destroyed by the next CPL filename handling call. The returned
* will generally not contain a trailing path separator.
*/
std::string UtilsGetDirname(const char *pszFilename)
{
const int iFileStart = UtilsFindFilenameStart(pszFilename);
if (iFileStart == 0) return ".";
return std::string(pszFilename, pszFilename + iFileStart - 1);
}
/************************************************************************/
/* UtilsGetFilename() */
/************************************************************************/
/**
* Extract non-directory portion of filename.
*
* Returns a string containing the bare filename portion of the passed
* filename. If there is no filename (passed value ends in trailing directory
* separator) an empty string is returned.
*
* <pre>
* UtilsGetFilename( "abc/def.xyz" ) == "def.xyz"
* UtilsGetFilename( "/abc/def/" ) == ""
* UtilsGetFilename( "abc/def" ) == "def"
* </pre>
*
* @param pszFullFilename the full filename potentially including a path.
*
* @return just the non-directory portion of the path (points back into
* original string).
*/
std::string UtilsGetFilename(const char *pszFullFilename)
{
const int iLen = static_cast<int>(strlen(pszFullFilename));
const int iFileStart = UtilsFindFilenameStart(pszFullFilename);
return std::string(pszFullFilename + iFileStart, pszFullFilename + iLen);
}
/************************************************************************/
/* UtilsGetBasename() */
/************************************************************************/
/**
* Extract basename (non-directory, non-extension) portion of filename.
*
* Returns a string containing the file basename portion of the passed
* name. If there is no basename (passed value ends in trailing directory
* separator, or filename starts with a dot) an empty string is returned.
*
* <pre>
* UtilsGetBasename( "abc/def.xyz" ) == "def"
* UtilsGetBasename( "abc/def" ) == "def"
* UtilsGetBasename( "abc/def/" ) == ""
* </pre>
*
* @param pszFullFilename the full filename potentially including a path.
*
* @return just the non-directory, non-extension portion of the path in
* an internal string which must not be freed. The string
* may be destroyed by the next CPL filename handling call.
*/
std::string UtilsGetBasename(const char *pszFullFilename)
{
const size_t iFileStart = static_cast<size_t>(UtilsFindFilenameStart(pszFullFilename));
size_t iExtStart = strlen(pszFullFilename);
for (;
iExtStart > iFileStart && pszFullFilename[iExtStart] != '.';
iExtStart--) {
}
if (iExtStart == iFileStart) iExtStart = strlen(pszFullFilename);
return std::string(pszFullFilename + static_cast<int>(iFileStart),
pszFullFilename + static_cast<int>(iExtStart));
}
/************************************************************************/
/* UtilsGetExtension() */
/************************************************************************/
/**
* Extract filename extension from full filename.
*
* Returns a string containing the extension portion of the passed
* name. If there is no extension (the filename has no dot) an empty string
* is returned. The returned extension will not include the period.
*
* <pre>
* UtilsGetExtension( "abc/def.xyz" ) == "xyz"
* UtilsGetExtension( "abc/def" ) == ""
* </pre>
*
* @param pszFullFilename the full filename potentially including a path.
*
* @return just the extension portion of the path in
* an internal string which must not be freed. The string
* may be destroyed by the next CPL filename handling call.
*/
std::string UtilsGetExtension(const char *pszFullFilename)
{
if (pszFullFilename[0] == '\0') return "";
size_t iFileStart = static_cast<size_t>(UtilsFindFilenameStart(pszFullFilename));
size_t sLen = strlen(pszFullFilename);
size_t iExtStart = strlen(pszFullFilename);
for (;
iExtStart > iFileStart && pszFullFilename[iExtStart] != '.';
iExtStart--) {
}
if (iExtStart == iFileStart)
return "";
// If the extension is too long, it is very much likely not an extension,
// but another component of the path
const size_t knMaxExtensionSize = 10;
if (sLen - iExtStart > knMaxExtensionSize) {
return "";
}
return std::string(iExtStart + 1 + pszFullFilename, pszFullFilename + sLen);
}
十二、c++开发时总结
1.单参数的构造函数(除去有默认参数,还有不带默认参数1的也是)要加上 explicit 关键字。
表明该构造函数是显示的, 而非隐式的。
2.如果定义的类申请了堆内存,那么建议添加深拷贝构造函数。(默认拷贝构造函数是浅拷贝,在隐藏的拷贝中容易造成内存泄漏)
3.一个人有做基类的情况时,同时该类申请了堆内存,那么该类的析构函数应该加上virtual关键字。(基类指针指向派生类delete时,派生类部分部分清除造成内存泄漏)
4.基类中即将被重写的函数添加virtual,是一条应该遵守的编码习惯。(虚基类可以解决二义性的问题 )
多继承和多重继承二义性的解决方法(第5、第6、第7点):
5.在有可能出现多层继承时,应该使用虚继承基类(保证基类只会调用一次);
6.子类访问父类成员数据可以指定父类名;
7.子类访问父类方法可以指定父类名或者重写方法再调用父类方法;
8.虚函数和虚基类在调用的时候是没有问题的,但是在delete的时候会发生堆报错。(delete的内存地址与new的内存地址不同,所以会造成问题,详情)
9.如果存在继承,调用基类方法或成员变量时建议用类名注明作用域。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)