هل مللت من مصفوفات الرموز فى السى++ صعبة المراس؟! الا تريد ان تعمل مع متغير حرفى شبيه بما يقدمه البيسك أو الدلفى؟
بالنسبة لى قمت بتصميم مكتبة صغيرة اسمها FString طبعا حرف F يشير الى اسمى:)
الFString كلاس سى++ يسهل التعامل مع مصفوفات الأحرف, و يجعلك تشعر أنك تتعامل مع البيسك أو الدلفى.
الFString ترجمت و نفذت بنجاح على فيجوال سى++ و تتبع لغة سى++ القياسية لذا فانها سوف تترجم على الأغلب مع اى مترجم أخر.
لنستعرضها معا.
FStr.h:
// FStr by Fadi Nabil Nashed
class FStr
{
public:
FStr(const char source[]="");
FStr(const FStr& source);
~FStr();
void operator= (const char source[]);
void operator= (const FStr& source);
bool operator==(const char*) const;
bool operator==(const FStr& cmp_str);
bool operator>(const char*) const;
bool operator>(const FStr& cmp_str);
bool operator<(const char*) const;
bool operator<(const FStr& cmp_str);
bool operator>=(const char*) const;
bool operator>=(const FStr& cmp_str);
bool operator<=(const char*) const;
bool operator<=(const FStr& cmp_str);
double GetFloat();
int GetInt();
int SearchStr(const char * search_str) const;
int SearchStr(const FStr& search_str);
void TrimLeft();
void TrimRight();
void Trim();
void CutStr(int begin,int length);
void SetStr(int location,const char * set_char);
void SetStr(int location,FStr& set_char);
void Insert(const char * set_char,int location);
void Insert(FStr& set_char,int location);
void operator+=(const FStr& add_str);
void operator+=(const char add_str[]);
friend FStr operator+(const FStr& lhs, const FStr& rhs);
char operator [](size_t position) const;
const char *GetChars() const;
int GetSize();
// For Compatability with VCL
int AnsiPos(const FStr& search_str);
int AnsiPos(const char * search_str) const;
const char *c_str() const;
int Length();
int Pos(const FStr& search_str);
int Pos(const char * search_str) const;
FStr SetLength(int new_length);
FStr SubString(int begin,int length);
double ToDouble();
int ToInt();
//-------------------------------------------
private:
char *str;
int len;
};
#include <stdlib.h>
الشرح:
المكتبة ببساطة تعرف مؤشر اسمه str, و طوله, كل ما علينا هو التعامل مع هذا المؤشر من خلال الكود و تنفيذ طلبات المستخدم عبر هذا المؤشر.
و طبعا يجب أن يكون السترينج قادرا على ارجاع نفسه فى صورة مصفوفة حرفية عادية حتى يمكن التعامل معه فى طلبات النظام مثلا لعرضه على الشاشة.
ننتقل الى الكود :
FStr.cpp
#include "fstr.h"
#include <string.h>
#include <math.h>
FStr::FStr(const char source[])
{
str=(char*)malloc(strlen(source));
strcpy(str,source);
}
// هنا الconstructor, و الذى يقوم بحجز الذاكرة اللازمة للمصفوفة الحرفية.
FStr::FStr(const FStr& source)
{
str=(char*)malloc(strlen(source.GetChars()));
strcpy(str,source.GetChars());
}
FStr::~FStr()
{
}
const char* FStr::GetChars() const
{
return str;
}
// هذه الدالة مهمة جدا, و هى تقوم بارجاع المتغير بشكله الأول حتى يمكن التعامل معه.
void FStr::operator= (const char source[])
{
str=(char*)malloc(strlen(source));
strcpy(str,source);
}
// عندما نقوم بمعادلة المتغير مع مصفوفة حرفية, تستقبل هذه الدالة السلسلة الحرفية و تقوم بنسخها لمتغيرها الداخلى.
void FStr::operator= (const FStr& source)
{
str=(char*)malloc(strlen(source.GetChars()));
strcpy(str,source.GetChars());
}
// نفس الحالة السابقة, و لكن عند معادلة الFstr مع مثله.
bool FStr::operator==(const char* cmp_str) const
{
return !strcmp(str,cmp_str);
}
//هنا للمقارنة بين الاف سترينج و مصفوفة حرفية, و نرجع عكس الدالة strcmp لأنها تعطى صفر فى حالة التساوى.
bool FStr::operator==(const FStr& cmp_str)
{
return !strcmp(str,cmp_str.GetChars());
}
//نفس الحالة السابقة لكن فى حالة مقارنة اثنين اف سترينج مع بعضهم.
int FStr::GetSize()
{
return strlen(str);
}
// هنا نقوم بارجاع طول المتغير.
void FStr::operator+=(const FStr& add_str)
{
strcat(str,add_str.GetChars());
}
// نقوم بمعالجة اضافة اف سترينج الى اخر بواسطة المعامل +=.
void FStr::operator+=(const char add_str[])
{
strcat(str,add_str);
}
// معالجة اضافة مصفوفة حرفية الى الاف سترينج.
FStr operator+(const FStr& lhs, const FStr& rhs)
{
FStr ss;
ss=lhs;
ss+=rhs;
return ss;
}
// نقوم بمعالجة اضافة اف سترينج الى اخر بواسطة المعامل +.
bool FStr::operator>(const char* cmp_str) const
{
int cmp_res;
cmp_res=strcmp(str,cmp_str);
if(cmp_res>0)
return true;
else
return false;
}
// مقارنة الاف سترينج مع مصفوفة حرفية بواسطة >
bool FStr::operator>(const FStr& cmp_str)
{
int cmp_res;
cmp_res=strcmp(str,cmp_str.GetChars());
if(cmp_res>0)
return true;
else
return false;
}
// مقارنة الاف سترينج مع مصفوفة حرفية بواسطة <
bool FStr::operator<(const char* cmp_str) const
{
int cmp_res;
cmp_res=strcmp(str,cmp_str);
if(cmp_res<0)
return true;
else
return false;
}
bool FStr::operator<(const FStr& cmp_str)
{
int cmp_res;
cmp_res=strcmp(str,cmp_str.GetChars());
if(cmp_res<0)
return true;
else
return false;
}
bool FStr::operator>=(const char* cmp_str) const
{
int cmp_res;
cmp_res=strcmp(str,cmp_str);
if(cmp_res>0 || cmp_res==0)
return true;
else
return false;
}
bool FStr::operator>=(const FStr& cmp_str)
{
int cmp_res;
cmp_res=strcmp(str,cmp_str.GetChars());
if(cmp_res>0 || cmp_res==0)
return true;
else
return false;
}
bool FStr::operator<=(const char* cmp_str) const
{
int cmp_res;
cmp_res=strcmp(str,cmp_str);
if(cmp_res<0 || cmp_res==0)
return true;
else
return false;
}
bool FStr::operator<=(const FStr& cmp_str)
{
int cmp_res;
cmp_res=strcmp(str,cmp_str.GetChars());
if(cmp_res<0 || cmp_res==0)
return true;
else
return false;
}
char FStr::operator [](size_t position) const
{
if(position>(strlen(str)-1))
return NULL;
return str[position];
}
// المفاجأة ان الاف سترينج هنا يستطيع أن يرجع اى رمز من رموزه و كانه مصفوفة, عكس حرفى البيسك مثلا.
double FStr::GetFloat()
{
double ff=0;
try{
ff=atof(str);
}
catch(...) {ff=0;}
return ff;
}
// اذا اردت ان يعطيك الاف سترينج قيمته فى شكل رقمى float
int FStr::GetInt()
{
int ii=0;
try{
ii=atoi(str);
}
catch(...) {ii=0;}
return ii;
}
// اذا اردت ان يعطيك الاف سترينج قيمته فى شكل رقمى int
int FStr::SearchStr(const char * search_str) const
{
int len;
bool equal=true;
len=strlen(search_str);
for(int i=0;i<strlen(str);i++)
{
if(str==search_str[0])
{
equal=true;
for(int u=0;u<strlen(search_str);u++)
{
if(str[i+u]!=search_str)
equal=false;
}
if(equal==true)
return (i+1);
}
}
return 0;
}
// هنا دالة البحث المفيدة جدا فنبحث داخل الاف سترينج فى مصفوفة حرفية.
int FStr::SearchStr(const FStr& search_str)
{
int len;
bool equal=true;
len=strlen(search_str.GetChars());
for(int i=0;i<strlen(str);i++)
{
if(str==search_str[0])
{
equal=true;
for(int u=0;u<strlen(search_str.GetChars());u++)
{
if(str[i+u]!=search_str)
equal=false;
}
if(equal==true)
return (i+1);
}
}
return 0;
}
// هنا دالة البحث و لكن من خلال اف سترينج.
void FStr::TrimLeft()
{
bool equal=true;
int space=0;
for(int i=0;i<strlen(str);i++)
{
if(str==' ')
{
if(space==0)
space=i;
}
if(str!=' ')
space=0;
}
if(space>0)
str[space]='\0';
}
// محاكاة لدالة Trim فى البيسك و التى تقوم بحذف المسافات الخالية من جوانب الحرفى, هذه تقوم بالحذف من اليسار.
void FStr::TrimRight()
{
bool equal=true;
int space=0;
char *temp_str;
temp_str=(char*)malloc(strlen(str));
for(int i=(strlen(str));i>-1;i--)
{
if(str==' ')
{
if(space==0)
space=i;
}
if(str!=' ')
space=0;
}
if(space>0)
{
for(int i=(space+1);i<strlen(str);i++)
temp_str[i-space-1]=str;
temp_str[i-space-1]='\0';
strcpy(str,temp_str);
}
}
// نفس الدالة السابقة و لكن الحذف من اليمين.
void FStr::Trim()
{
TrimLeft();
TrimRight();
}
// الحذف من الجهتين.
void FStr::CutStr(int begin,int length)
{
char *temp_str;
temp_str=(char*)malloc(strlen(str));
for(int i=begin;i<(begin+length);i++)
{
temp_str[i-begin]=str;
}
temp_str[i-begin]='\0';
strcpy(str,temp_str);
}
// تقوم هذه الدالة بقص الاف سترينج من اول مكان معين و بعدد معين من الأحرف.
void FStr::SetStr(int location,const char * set_char)
{
for(int i=location;i<(location+strlen(set_char));i++)
{
str=set_char[i-location];
}
}
// تقوم هذه الدالة بعمل ما يشبه الReplace من اول مكان معين.
void FStr::SetStr(int location,FStr& set_char)
{
for(int i=location;i<(location+strlen(set_char.GetChars()));i++)
{
str=set_char[i-location];
}
}
void FStr::Insert(const char * set_char,int location)
{
char *temp_str;
char *temp_str2;
int i=0;
temp_str=(char*)malloc(strlen(str));
for(i=0;i<(location);i++)
{
temp_str=str;
}
temp_str='\0';
strcat(temp_str,set_char);
temp_str2=(char*)malloc(strlen(str));
for(i=location;i<(location+strlen(str));i++)
{
temp_str2[i-location]=str;
}
temp_str[i-location]='\0';
strcat(temp_str,temp_str2);
strcpy(str,temp_str);
}
// تقوم هذه الدالة بعمل Insert من مكان محدد لمصفوفة حرفية.
void FStr::Insert(FStr& set_char,int location)
{
char *temp_str;
char *temp_str2;
int i=0;
temp_str=(char*)malloc(strlen(str));
for(i=0;i<(location);i++)
{
temp_str=str;
}
temp_str='\0';
strcat(temp_str,set_char.GetChars());
temp_str2=(char*)malloc(strlen(str));
for(i=location;i<(location+strlen(str));i++)
{
temp_str2[i-location]=str;
}
temp_str[i-location]='\0';
strcat(temp_str,temp_str2);
strcpy(str,temp_str);
}
int FStr::AnsiPos(const FStr& search_str)
{
int len;
bool equal=true;
len=strlen(search_str.GetChars());
for(int i=0;i<strlen(str);i++)
{
if(str==search_str[0])
{
equal=true;
for(int u=0;u<strlen(search_str.GetChars());u++)
{
if(str[i+u]!=search_str)
equal=false;
}
if(equal==true)
return (i+1);
}
}
return 0;
}
// الدوال القادمة تؤدى نفس مهمة الدوال السابقة و لكننى كتبتها شبيه بمكتبة الVCL المستخدمة فى الدلفى و السى++ بيلدر كنوع من التسهيل على من يتعامل مع مكتبات بورلاند.
int FStr::AnsiPos(const char * search_str) const
{
int len;
bool equal=true;
len=strlen(search_str);
for(int i=0;i<strlen(str);i++)
{
if(str==search_str[0])
{
equal=true;
for(int u=0;u<strlen(search_str);u++)
{
if(str[i+u]!=search_str)
equal=false;
}
if(equal==true)
return (i+1);
}
}
return 0;
}
const char * FStr::c_str() const
{
return str;
}
int FStr::Length()
{
return strlen(str);
}
int FStr::Pos(const FStr& search_str)
{
return SearchStr(search_str);
}
int FStr::Pos(const char * search_str) const
{
return SearchStr(search_str);
}
FStr FStr::SetLength(int new_length)
{
char *str_new;
str_new=(char*)malloc(strlen(str));
if(new_length>strlen(str))
return "";
strcpy(str_new,str);
str_new[new_length]='\0';
return str_new;
}
FStr FStr::SubString(int begin,int length)
{
char *temp_str;
temp_str=(char*)malloc(strlen(str));
for(int i=begin;i<(begin+length);i++)
{
temp_str[i-begin]=str;
}
temp_str[i-begin]='\0';
return temp_str;
}
double FStr::ToDouble()
{
return GetFloat();
}
int FStr::ToInt()
{
return GetInt();
}
#include "stdafx.h"
الشرح داخل الكود.