اوشكت على الإنتهاء بفضل الله من مكتبة StrLib للغة الـ C و الـ Cpp.
داخل لغة الـ Cpp قمت بتضمين المكتبه على شكل فئه نصوص اسميتها StringA و هى تتعامل مع نصوص ANSI فقط (إن شاء الله الإصدارات القادمه سأضيف فئات لليونيكود)، داخل فئة StringA قمت بإضافة الدوال التاليه:
// flags for string operations
enum StringFlags
{
None = 0, // empty flag, mean use function default flag
SearchStepWord = 1, // used in CountOf and IndexesOf
SearchStepChar = 2, // used in CountOf and IndexesOf
IgnoreCharCase = 4, // used in CountOf and IndexesOf and Split
RemoveEmptyEntries = 8 // used in Split
};
class StringA
{
// public static fields
public:
// empty ascii string
static const StringA Empty;
// constructors & destructor
public:
StringA();
StringA(const achar chr);
StringA(const astr str);
StringA(const astr str, int32 start_index, int32 length);
StringA(const StringA& str);
StringA(const StringA& str, int32 start_index, int32 length);
~StringA();
// instance member functions
public:
// append str to current instance
StringA& Append(const StringA& str);
// get character at specified index
achar& CharAt(int32 index);
// duplicate current instance
StringA& Clone();
// determined if current instance contains str
bool Contains(const StringA& str);
bool Contains(const StringA& str, bool ignoreCase);
// get count of str in current instance
int32 CountOf(const StringA& str);
int32 CountOf(const StringA& str, StringFlags flag);
int32 CountOf(const StringA& str, int32 start_index);
int32 CountOf(const StringA& str, int32 start_index, StringFlags flag);
int32 CountOf(const StringA& str, int32 start_index, int32 length);
int32 CountOf(const StringA& str, int32 start_index, int32 length, StringFlags flag);
// is current instance ends with str
bool EndsWith(const StringA& str);
bool EndsWith(const StringA& str, bool ignoreCase);
// get current nstance hash code
int32 GetHashCode();
// get c style string
astr GetNativeString();
astr GetNativeString(int32 start_index);
astr GetNativeString(int32 start_index, int32 length);
// get index of find in current instance
int32 IndexOf(const StringA& find);
int32 IndexOf(const StringA& find, bool ignoreCase);
int32 IndexOf(const StringA& find, int32 start_index);
int32 IndexOf(const StringA& find, int32 start_index, bool ignoreCase);
int32 IndexOf(const StringA& find, int32 start_index, int32 length);
int32 IndexOf(const StringA& find, int32 start_index, int32 length, bool ignoreCase);
// get index of any character from find that exist in current instance
int32 IndexOfAny(const StringA& findAny);
int32 IndexOfAny(const StringA& findAny, bool ignoreCase);
int32 IndexOfAny(const StringA& findAny, int32 start_index);
int32 IndexOfAny(const StringA& findAny, int32 start_index, bool ignoreCase);
int32 IndexOfAny(const StringA& findAny, int32 start_index, int32 length);
int32 IndexOfAny(const StringA& findAny, int32 start_index, int32 length, bool ignoreCase);
// get indexes of find string in current instance
int32* IndexesOf(const StringA& find, int32& resultLen);
int32* IndexesOf(const StringA& find, StringFlags flag, int32& resultLen);
int32* IndexesOf(const StringA& find, int32 start_index, int32& resultLen);
int32* IndexesOf(const StringA& find, int32 start_index, StringFlags flag, int32& resultLen);
int32* IndexesOf(const StringA& find, int32 start_index, int32 length, int32& resultLen);
int32* IndexesOf(const StringA& find, int32 start_index, int32 length, StringFlags flag, int32& resultLen);
// insert str in cuurent instance at specified index
StringA& Insert(const StringA& str, int32 start_index);
// is current instance in lower case
bool IsLower();
bool IsLower(int32 start_index);
bool IsLower(int32 start_index, int32 length);
// is current instance in upper case
bool IsUpper();
bool IsUpper(int32 start_index);
bool IsUpper(int32 start_index, int32 length);
// is current instance in whitespace
bool IsWhitespace();
bool IsWhitespace(int32 start_index);
bool IsWhitespace(int32 start_index, int32 length);
// get last index of find in current instance
int32 LastIndexOf(const StringA& find);
int32 LastIndexOf(const StringA& find, bool ignoreCase);
int32 LastIndexOf(const StringA& find, int32 start_index);
int32 LastIndexOf(const StringA& find, int32 start_index, bool ignoreCase);
int32 LastIndexOf(const StringA& find, int32 start_index, int32 length);
int32 LastIndexOf(const StringA& find, int32 start_index, int32 length, bool ignoreCase);
// get last index of any character from find that exist in current instance
int32 LastIndexOfAny(const StringA& findAny);
int32 LastIndexOfAny(const StringA& findAny, bool ignoreCase);
int32 LastIndexOfAny(const StringA& findAny, int32 start_index);
int32 LastIndexOfAny(const StringA& findAny, int32 start_index, bool ignoreCase);
int32 LastIndexOfAny(const StringA& findAny, int32 start_index, int32 length);
int32 LastIndexOfAny(const StringA& findAny, int32 start_index, int32 length, bool ignoreCase);
// get current instance lenght
int32 Length() const;
// match current instance aginest pattren
bool Like(const StringA& pattren);
bool Like(const StringA& pattren, bool ignoreCase);
bool Like(const StringA& pattren, int32 start_index);
bool Like(const StringA& pattren, int32 start_index, bool ignoreCase);
bool Like(const StringA& pattren, int32 start_index, int32 length);
bool Like(const StringA& pattren, int32 start_index, int32 length, bool ignoreCase);
// pad current instance to left with requested size
StringA& PadLeft(int32 size);
StringA& PadLeft(int32 size, const achar chr);
// pad current instance to right with requested size
StringA& PadRight(int32 size);
StringA& PadRight(int32 size, const achar chr);
// remove range from current instance
StringA& Remove(int32 start_index);
StringA& Remove(int32 start_index, int32 length);
// remove val from current instance
StringA& Remove(const StringA& val);
StringA& Remove(const StringA& val, bool ignoreCase);
StringA& Remove(const StringA& val, int32 start_index);
StringA& Remove(const StringA& val, int32 start_index, bool ignoreCase);
StringA& Remove(const StringA& val, int32 start_index, int32 length);
StringA& Remove(const StringA& val, int32 start_index, int32 length, bool ignoreCase);
// overwrite find string with replace string in current instance
StringA& Replace(const StringA& find, const StringA& replace);
StringA& Replace(const StringA& find, const StringA& replace, bool ignoreCase);
StringA& Replace(const StringA& find, const StringA& replace, int32 start_index);
StringA& Replace(const StringA& find, const StringA& replace, int32 start_index, bool ignoreCase);
StringA& Replace(const StringA& find, const StringA& replace, int32 start_index, int32 length);
StringA& Replace(const StringA& find, const StringA& replace, int32 start_index, int32 length, bool ignoreCase);
// reverse current instance
StringA& Reverse();
StringA& Reverse(IN int32 start_index);
StringA& Reverse(IN int32 start_index, IN int32 length);
// split current instance using seprator
StringA* Split(const StringA& seprator, int32& resultLen);
StringA* Split(const StringA& seprator, StringFlags flag, int32& resultLen);
StringA* Split(const StringA& seprator, int32 start_index, int32& resultLen);
StringA* Split(const StringA& seprator, int32 start_index, StringFlags flag, int32& resultLen);
StringA* Split(const StringA& seprator, int32 start_index, int32 length, int32& resultLen);
StringA* Split(const StringA& seprator, int32 start_index, int32 length, StringFlags flag, int32& resultLen);
// is current instance starts with val
bool StartsWith(const StringA& val);
bool StartsWith(const StringA& val, bool ignoreCase);
// substring range from current instance
StringA& Substring(int32 start_index);
StringA& Substring(int32 start_index, int32 length);
// convert current instance to lower case
StringA& ToLower();
StringA& ToLower(int32 start_index);
StringA& ToLower(int32 start_index, int32 length);
// convert current instance to upper case
StringA& ToUpper();
StringA& ToUpper(int32 start_index);
StringA& ToUpper(int32 start_index, int32 length);
// trim current instance
StringA& Trim();
StringA& TrimEnd();
StringA& TrimStart();
// overloaded operators goes here
// +
// +=
// =
// ==
// !=
// []
// >> pad string left
// << pad string right
// class member functions
public:
// compaer two strings
static bool Compare(const StringA& s1, const StringA& s2);
static bool Compare(const StringA& s1, const StringA& s2, bool ignoreCase);
static bool Compare(const StringA& s1, const StringA& s2, int32 s1_start_index);
static bool Compare(const StringA& s1, const StringA& s2, int32 s1_start_index, bool ignoreCase);
static bool Compare(const StringA& s1, const StringA& s2, int32 s1_start_index, int32 length);
static bool Compare(const StringA& s1, const StringA& s2, int32 s1_start_index, int32 length, bool ignoreCase);
static bool Compare(const StringA& s1, const StringA& s2, int32 s1_start_index, int32 s2_start_index, int32 length);
static bool Compare(const StringA& s1, const StringA& s2, int32 s1_start_index, int32 s2_start_index, int32 length, bool ignoreCase);
// concat 2 strings
static StringA& Concat(StringA& s1, StringA& s2);
// concat array of strings
static StringA& Concat(StringA arrStr[], int32 size);
static StringA& Concat(StringA arrStr[], int32 size, StringA& delimit);
static StringA& Concat(StringA arrStr[], int32 size, int32 start_index);
static StringA& Concat(StringA arrStr[], int32 size, int32 start_index, int32 length);
static StringA& Concat(StringA arrStr[], int32 size, int32 start_index, StringA& delimit);
static StringA& Concat(StringA arrStr[], int32 size, int32 start_index, int32 length, StringA& delimit);
// is str empty
static bool IsEmpty(StringA& str);
// repeat str specified number of times
static StringA& Repeat(const StringA& str, int32 repeatCount);
static StringA& Repeat(const StringA& str, int32 start_index, int32 repeatCount);
static StringA& Repeat(const StringA& str, int32 start_index, int32 length, int32 repeatCount);
// convert 8-bit signed number to string
static StringA& ToString(int8 val);
static StringA& ToString(int8 val, const StringA& format);
// convert 8-bit unsigned number to string
static StringA& ToString(uint8 val);
static StringA& ToString(uint8 val, const StringA& format);
// convert 16-bit signed number to string
static StringA& ToString(int16 val);
static StringA& ToString(int16 val, const StringA& format);
// convert 16-bit unsigned number to string
static StringA& ToString(uint16 val);
static StringA& ToString(uint16 val, const StringA& format);
// convert 32-bit signed number to string
static StringA& ToString(int32 val);
static StringA& ToString(int32 val, const StringA& format);
// convert 32-bit unsigned number to string
static StringA& ToString(uint32 val);
static StringA& ToString(uint32 val, const StringA& format);
// convert 64-bit signed number to string
static StringA& ToString(int64 val);
static StringA& ToString(int64 val, const StringA& format);
// convert 64-bit unsigned number to string
static StringA& ToString(uint64 val);
static StringA& ToString(uint64 val, const StringA& format);
// convert 32-bit float number to string
static StringA& ToString(float val);
static StringA& ToString(float val, const StringA& format);
// convert 64-bit float number to string
static StringA& ToString(double val);
static StringA& ToString(double val, const StringA& format);
// format string with variable number of argument
static StringA& Format(const StringA& value, ...);
// private static methods
private:
// memory allocation used by StringA class
static blob MemoryAlloc(uint32 size);
static blob MemoryResize(blob ptr, uint32 size);
static bool MemoryFree(blob ptr);
static int32 StringLenth(const astr str);
// private methods
private:
// initialize current instance
void InitFromPointer(const astr str, int32 start_index, int32 length);
void InitFromStringA(const StringA& str, int32 start_index, int32 length);
// private fields
private:
int* mLen; // pointer to string size.
astr mStr; // pointer to c-string.
};اسئلتى هى كالتالى:
1 - المعامل == المفترض انه سيقارن بين نصين، اسلوب المقارنه هل سيكون بإستخدام الداله Compare ام بإستخدام الداله GetHashCode ام بإستخدام الداله Length ؟
2 - مجموعة دوال ToString المفترض انها ستقوم بتحويل رقم لنص عن طريق format معين سيتم ادخاله عن طريق المستخدم، حتى الأن لا توجد صيغ فى رأسى و لا اعرف من اين احصل عليهم.
3 - الداله Format، هذه الداله حيرتنى كثيرا فأنا لا أريدها ان تعمل مثل printf فى اسلوب تمرير المعاملات داخلها فالداله printf لا تتيح تحديد رقم المعامل الذى سيتم دمجه داخل النص و إنما تأخذهم بشكل تدريجى الأول قالثانى و هكذا.
بالنسبه للداله GetHashCode فأنا استخدام خوارزمية SDBM و هى سريعه جدا و احتمالات تشابه النتائج لمختلف النصوص لها تقارب الصفر و لكن ليست صفر بالنسبه للداله Compare فنتائج المقارنه بها دقيقه جدا و ايضا سريعه جدا، بالنسبه للداله Length فهل من المنطقى اعادة تعريف المعامل == لنص مع رقم كأن يريد المستخدم مثلا مقارنة طول النص برقم مدخل ؟؟
ارجو افادتى فى اقرب وقت ان امكن، و مرحب بالإضافات و التعديلات
و الله ولى التوفيق