دوال التعامل مع الحروف و السلاسل الحرفية

بسم الله الرحمن الرحيم

دوال التعامل مع الحروف و السلاسل الحرفية

 


هنا نتطرق إلى دوال بعيدة كل البعد عن الدوال السابقة الذكر فالدوال السابقة هي دوال تزيين و تحسين مخرجات فقط .

 أما هنا فسنتطرق إلى دوال مهمة للمبرمج نفسة و لطبيعة برنامجة العملية .
منها:

 أولاً: الدوال التي تهتم بالحروف و هي تندرج تحت ملف الامتداد ctype.h .

_________________________________________________________________________________________________________________________________


1. الدالة
 

int isalnum ( char ch );
 

و هذه الدالة تتأكد من إذا كان الحرف المدخل من الأعداد 0 – 9 أو من الحروف A-Z أو a-z , فإذا كان المدخل رقم او حرف

 فإن الدالة تعيد القيمة غير الصفر ( غالباُ واحد ) و إذا لم يكن حرف و لا رقم فإن الدالة تعيد القيمة صفر . ولنفسر اسم هذه الدالة بالغلة الإنكليزية يكون:

Is Alphabetic  or is Number ?

لنرى كيف نستخدمها :
 

char ch = 'y' ; // or any number from 0 - 9
if ( isalnum (ch) != 0 )
     printf("%c is alphanumeric. n");
 

و من هنا يتضح كيف نستخدمها .

_________________________________________________________________________________________________________________________________

2. الدالة :
 

int isalpha ( char ch);
 

ولها نفس خصائص الدالة أعلاة و لكنها تختلف عن سابقتها بأنها تعيد صفر حتى ولو كان قيمة الـ ch عدد .

 

_________________________________________________________________________________________________________________________________

3. الدالة:
 

 

وصفها الدالة
Function Key تسأل إذا كان int iscntrl ( char ) ;
تسأل إذا كان رقم int isdigit ( char ) ;
  Space تتأكد إذا كان الحرف قابل للطباعة ولكن من غير الــ int isgraph( char ) ;
 تسأل إذا كان نوع الحرف صغير int islower( char ) ;
تسأل إذا كان الحرف قابل للطباعة و يتضمن من ذلك المسافة int isprint ( char ) ;
يسأل إذا كان الحرف المدخل مسافة int isspace( char ) ;
 يسأل إذا كان نوع الحرف كبير int isupper ( char ) ;
 hex يسأل إذا كان الحرف من نوع int isxdigit ( char ) ;

 



 طبعاً أنا ذكرت جميع الدوال على هذه الصيغة:
 

int theFunction ( char ) ;
 

في الحقيقة هذه الدوال لا تأخذ قيمة من نوع char بل تأخذها من نوع int أي الآسكي كود تبع الحرف .

 ولكن إذا أرسلت لأحد الدوال متغير من نوع int سيقبل و لكن على أساس أنه كود آسكي . و قد وضعت انا المتغيرات من نوع char وذلك لتسهيل فهم الدوال .
ولكن ألا تلاحظ أن جميع هذه الدوال تبدأ بالكلمة is ؟
والكلمة is تدل في الاجليزية على صيغة سؤال و السؤال جوابة يكون إما رفض و هو القيمة صفر ( 0 ) و إما قبول و هي غير تلك القيمة.

وهذ مثال يحسب عدد الحروف و الأرقام في جملة معينة :
 

#include "stdio.h"
#include "ctype.h"
void main()
{
        char str[10] ;
        int d_count ;      // digit counter
        int c_count ;      // char counter
        int i;                 // for the loop

        d_count = c_count = i = 0 ;

        printf(" Please Enter a string: ");
        gets(str);

        while ( str[i] != '' )
        {
                if( isalpha(str[i]) != 0 )
                    c_count++ ;
                else if ( isdigit (str[i]) != 0 )
                    d_count++ ;
            i++ ;
        }

        printf("There is %d digits and %d chat... ",d_count, c_count);
    return 0 ;
}
 

لاحظوا أن هذه الدوال تأخذ حرف واحد و ليست جملة.


ويوجد هناك ايضاً داتين هما :
 

char toupper ( char ch) ;
char tolower ( char ch) ;
 

و تستخدمان هكذا :
 

char ch = 'Y' ;
char cc ;
cc = tolower ( ch ) ;
 

و هكذا تستخدم الدالة toupper و اسم هاتين الدالتين تدلان على معناهما.
ولكن هاتين الدالتين للحروف فقط ... ولكن ماذا لو أردنا للكلمات أي للجمل ؟
الحل لن يخرج عن حلين :
الاول : إستخدام while loop و الأخر دالة سنتطرق لها بعد قليل .

 

_________________________________________________________________________________________________________________________________

يهذا نكون انهينا تقريباً دوال التعامل مع الحروف و الآن ننتقل إلى دوال التعامل مع الجمل وهي تندرج تحت الملف string.h وهذه هي :

1. الدالة
 

int strlen ( chat *s) ;
 

فلو كانت عندنا مصفوفة حرفية كالتالي:
 

int length ;
char str[20] = "Hi I am Talal" ;
 

ثم إستدعينا الدالة كالتالي:
 

Length = strlen (str) ;
 

ماذا سوف تكون النتيجة ؟
هل ستقول 20 الجواب قطعاً لا ...20 هو حجم المصفوفة و لكن طول الجملة هو 13.

 و سترى فائدتها في مثال شامل لكل هذه المفاهيم بعد قليل إن شاء الله .

 

_________________________________________________________________________________________________________________________________

2. الدالة :
 

char *strcat ( char *des, const char *str ) ;
 

وظيفتها هي إلحاق الجملة الثانية في نهاية الجملة الألى و تعيد الدالة مؤشر إلى الدالة المضاف إليها.

 ولكن ليس من الضروري ان تجعل هناك مؤشر للجملة المعدلة و لكن الجملة des ستعدل أوتوماتيكياً.

 

_________________________________________________________________________________________________________________________________

4. الدالة :
 

char *strncat ( char *des, const char *str, int n) ;
 

وهي نفس الدالة السابقة ولكن تضيف أول n حرف من str إلى الـ des حيث أن الـn هي قيمة من نوع int أي قيمة صحيحة .

 

_________________________________________________________________________________________________________________________________

5. الدالة:
 

int strcmp( const char *string1, const char *string2 );
 

و الجدول أدناه يبين كيفية تحديد قيم المقارنه:

< 0 string1 less than string2
0 string1 Equal to string2
> 0 string1 greater than string2

 



ومثلها الدالة strncmp و لكنها تأخذ متغير ثالث وهو عدد الحروف المراد مقارنتها .
فمثلاً لو كان لدينا برنامج به مجموعة أسماء و اردنا أن نعرف كم واحد يبدأ إسمة بـــ"عبد" مثل عبدالله و عندالرحمن و .... إلخ
الاحرف المشتركة بين هذه الاسماء هي عبد فقط و لذلك نستخدم الدالة strncmp و نعطي المتغير الثالث قيمة 3 هكذا :
 

int a ;
char *str1 = "abdullah", *str2 = "abdurahman" ;
a = strncmp(str1, str2, 3) ;
 

هنا ستعيد الدالة صفر للمتغير a.


 

_________________________________________________________________________________________________________________________________

6. الدالة:
 

char *strcpy( char *des, const char *str ) ;
 

وهذه الدالة تنسخ محتويات الجملة الثانية في الجملة الأولى و يتم مسح ما في الجملة الأولى. مثال هذه الدالة سيكون مع الدالة القدمة.

 

_________________________________________________________________________________________________________________________________

7. الدالة:
 

char *strchr ( const char *s, char c ) ;
 

وظيفة هذه الدالة هي البحث عن المتغير c في الجملة s , وتعيد مؤشر على الحرف إذا كان موجود .
لنرى هذا المثال :
 

#include "string.h"
#include "stdio.h"
int main(void)
{
        char string[15];
        char *ptr, c = 'r';

        strcpy(string, "This is a string");
        ptr = strchr(string, c);
        if (ptr) // OR if( ptr != NULL )
           
printf("The character %c is at position: %dn", c, ptr-string);
        else
            printf("The character was not foundn");
    return 0;
}
 

وتعيد الدالة NULL إذا لم يوجد الحرف المراد البحث عنه .
في هذا المثال عرفنا مصفوفة string تتكون من 15 حرف , ثم إستدعينا الدالة strcpy لستنخ الجلمة This is a string إلى المتغير string , ثم جعلنا بالدالة strchr المتغير ptr يشرإلى الحرف الموجود بالمتغير c الذي هو r , ثم تحققنا إذا كانت الـ ptr تساوي null فهذا معناه أن الحرف الموجود بالمتغير c غير موجود بالجملة string .
 

هذه هي أهم الدوال الموجوده في الملف string.h و ليست كلها بل اهمها . وهناك بعض الدوال سأذكرها بسرعة و لن اشرحها :
الدالتين :
 

char *strlwr(char *s) ;
char *strupr(char *s) ;
 

الدالة strlwr تحول جميع الحروف التي بالحالة الكبيرة إلى الحالة الصغيرة و الدالة strupr تعمل العكس, وهذه هي الدالة التي لمحت عليها من قبل.

 

_________________________________________________________________________________________________________________________________

الدالة :
 

char *strstr( const char *str, const char *str_set) ;
 

هذه دالة للبحث عن جملة داخل الجملة , إذا كانت موجوده في فإن الدالة تعيد مؤشر إلى أول حرف من str_set داخل str .

 أما إذا كانت غير موجودة فإن القيمة NULL تعاد من الدالة .
 


 

_________________________________________________________________________________________________________________________________

الدالة:
 

char *strpbrk(const char *str, const char *str_char_set) ;
 

هذه الدالة تبحث عن أي حرف من الجملة str_char_set  داخل الجملة str فعندما تصادف أول حرف في من الحروف الموجودة في str_char_set تعيد الدالة مؤشراً إلى ذلك الحرف , وإذا لم تكن أي من حروف موجودة فإن الدالة تعيد NULL . لنرى هذا المثال الذي يعمل على إزالت أي علامة من العلامات التالية {.,!;'/?-} من النص المدخل :
 

#include "string.h"
#include "stdio.h"
void main(void)
{
        char text[80] ;
        char *ptr ;

        printf("Enter a string contaning puncuations: n");
        gets(text);
        ptr = text ;

        while(ptr != '')
        {
            ptr = strpbrk(ptr, ".,!;'/-/" );
            if(ptr != '')
                *ptr = ' ';
        }
        printf("n%snn",text);
    return 0;
}
 

_________________________________________________________________________________________________________________________________

الدالة :
 

char *strrev(char *s) ;
 

لا تعليق على هذه الدالة فقط قوموا بتنفيذ هذا البرنامج وسترون النتيجة:
 

#include "string.h"
#include "stdio.h"
void main()
{
        char text[80] ;
        char *ptr ;

        printf("Enter a string contaning puncuations: n");
        gets(text);
        ptr = text ;

        while(ptr != '')
        {
            ptr = strpbrk(ptr, ".,!;'/-/" );
            if(ptr != '')
                *ptr = ' ';
        }
        printf("n%snn",text);
}
 

_________________________________________________________________________________________________________________________________

الدالة :
 

char *strset ( char *s , char ch ) ;
 

وهذه الدالة تقوم بتغيير جميع حروف الجملة s إلى المتغير ch شوفوا هذا المثال للتوضيح :
 

#include "stdio.h"
#include "string.h"
int main(void)
{
        char string[10] = "123456789";
        char symbol = 'c';

        printf("Before strset(): %sn", string);
        strset(string, symbol);
        printf("After strset(): %sn", string);
    return 0;
}
 

دعونا نأخذ بعض التمارين قبل الدخول في دوال الـ stdlib.h.

طيب طلب منا السؤال أن نحسب كم كلمة of موجوده في القطعة التالية :
 

The strstr() function searchs for first occurrence of a substring within a string. If the sub string is found, strstr() returns a pointer to the begging of the substring. If the substring is not found, strstr() returns the null value.
 

الحل ببساطة هو إستخدام الدالة strstr وسيكون الحل هكذا :
 

#include "stdio.h"
#include "string.h"
void main()
{
        char text[] = "The strstr() function searchs for"
                            "first occurrence of a substring within"
                            "a string."
                            "If the sub string is found, strstr() returns"
                            "a pointer to the beging of the substring."
                            "If the substring is not found, strstr()"
                            "returns the null value." ;
        char *ptr ;
        int of_cont = 0 ;

        ptr = text ;
        do
        {
            ptr = strstr(ptr,"of");
            if( ptr != '')
            {
                of_count++;
                ptr++ ;
            }
        }while(ptr != '') ;
    printf("nThe word 'of' appers %d times.nn");
}
 

 

إلى هنا نتوقف عن مكتبة الـ string.h ولو أنه يوجد أيضا الكثير مما لم نقف عندها إطلاقاً و لكن هذه الدوال كافية جدا لعمل اعقد البرامج .


الآن ننطلق مع مجموعة صغيرة من دوال الـ stdlib.h :
سنختصر هذه الدوال إلى دوال الــ convert من عدد إلى جملة ومن جملة إلى عدد و هي مهمة جدا جدا جدا و سنأخذ مثال عملي لأهميتها في آخر هذا الدرس .
 

_________________________________________________________________________________________________________________________________

1. دالة :
 

int atoi( const char *s) ;
 

وهذه الدالة تحول الجملة المكونه من أرقام إلى أعدد صحيحة من نوع int يمكن التعامل معها بالضرب و الجمع كأي عدد آخر.
إذا كانت الجملة مثلاً 1234m56 فالجملة المعادة هي 1234 تحول الجملة إلى أعداد حتى تصل إلى أول حرف ليس برقم و كذلك الحال لو إستبدلنا الحرف m في الجملة السابقة بالعلامة '.' سيكون المخرج نفسة .
لنرى هذه المثال على كيفية إستخدامها :

#include "stdlib.h"
#include"stdio.h"
int main(void)
{
        int n;
        char *str = "1234m56";

        n = atoi(str);
        printf("string = %s integer = %dn", str, n);
    return 0;
}
 

إذا لم يكن هناك مجال لتحويل الجملة مثل الجملة '' 12345. '' فالدالة تعيد القيمة صفر .
_________________________________________________________________________________________________________________________________

2. الدالة :
 

float atof(const char *s ) ;
 

وهي تعمل نفس عمل الدالة السابقة و لكن تغير إلى float و ليس int .
لنرى هذا المثل :
 

#include "stdlib.h"
#include "stdio.h"

int main(void)
{
        float n;
        char *str = "1234.56";

        n = atoi(str);
        printf("string = %s float = %.2fn", str, n);
    return 0;
}
 

_________________________________________________________________________________________________________________________________

3. الدالة :
 

char *itoa(int value, char *string, int readx ) ;
 

هذه الدالة تحول الرقم value إلى جملة في المتغير string
و دائماً إجعل الـ readx قيمتها 10 .

و السبب في ذلك كما هو من أجل التحويل للقيم السالبة و هذا هو نص ما قالته مايكروسوفت بهذا الخصوص:

If radix equals 10 and value is negative, the first character of the stored string is the minus sign ( – ).


و لنرى هذا المثال :
 

#include "stdlib.h"
#include "stdio.h"

int main(void)
{
        int number = -12345;
        char string[25];

        itoa(number, string, 10);
        printf("integer = %d string = %sn", number, string);
    return 0;
}
 

والصراحة بحثت إن كان هناك دالة تحول من نوع float إلى جملة فلم أجد للأسف .


ولكن يجب  أن تكون حذر عند إستخدام هذه الدالة و تتأكد من حجم المصفوفة التي ستضع العدد بها لا تجعلها صغيرة ولكي تريح بالك من هذه المشكلة قم بالتعريف التالي على الكود السابق:
 

char *string ;
 

نفذ الآن ستلاحظ ان الدالة ستعيد NULL ؟!؟! إذاً ماهو الحل :
قم بوضع هذا السطر قبل ان تستخدم المتغير string :
 

string = (char*) malloc(sizeof(char)) ;
 

بهذا السطر سيعمل برنامجك 100%.

طبعاً أخذنا الدالة isalpha و isdigit ولكن هذه الدوال لا تعمل على الجمل بل على الأحرف فقط إذاً ما هو الحال ؟!؟
لنرى هذة الدالة التي تقوم بعمل الدالة isalpha ولكن للجمل ...
فهي تعيد صفر إذا كانت أحد حروف الجملة غير حرف و تعيد واحد إذا كانت حروف الجملة جميعها حروف أو مسافات .
 

#include "stdlib.h"
#include "stdio.h" // for malloc only
#include "ctype.h"
#include "conio.h"
int isalphas(const char *s);
main()
{
        char *s;
        clrscr();
        s = (char*) malloc(sizeof(char));
        gets(s);
        if(isalphas(s) != 0 )
            printf("all are alphabit ...");
        getch();
    return 0;
}
int isalphas(const char *s )
{
        int i,t,s;
        i = 0;
        t = 1;
       
while( a[i] != '' && t == 1 )
        {
            s = isalpha( a[i] );
           
if(s == 0)
            {
               
if(a[i]!=' ' && a[i]!='_')
                    t=0;
            }
            i++;
        }
           
if(a[0]=='')
                t=0;
   
return t;
}
 

ولكن ماذا لو أرد أن تعمل برنامج لإدخال إيميل الإي ميل طبعاً سيحتوي على علامة @ أو من الممكن ان يحتوي على علامة _ ماهو الحل ؟!؟
نفس البرنامج السابق ولكن غير الشرط الذي داخل الدالة isalphas إلى
 

if( s[i] != ' ' && s[i] != '@' && s[i] != '_')
      t =  0;
 

فهذا كافي لحل الإشكال ...



الآن قبل النهاية سنأخذ مثال لحل أكبر إشكال قد يواجه أي مبرمج ..
فلو كنت قد عملت برنامج وطلبت من المستخدم ان يدخل عدد ( تأكدوا عدد وليس حرف ) ماذا سيحدث ؟!؟!
مثل هذا البرنامج :
 

int a;
printf("nPlease Enter a number: ");
scanf("%d",&a);
 

فلو أدخل المستخدم اي حرف مثلاً g ستكون النتيجة وخيمة قد تنهي البرنامجح فوراً !!!
الحل هو أن ندخلها على شكل مصفوفة من نوع char ومن ثم نتأكد من إن كانت حروف من الدالة التي كتبتها أعلاه مع بعض الإختلافات وبعدها نحول الجملة إلى int أو float حسب ما نريد.. لنرى البرنامج الآن:
 

#include "stdlib.h"
#include "stdio.h"
#include "ctype.h"
#include "conio.h"

int isdigits(const char *str);

main()
{
        char s[30] ;
        int y ;
        long value ;

        printf("nEnter a value: ");
        gets(s);
        y=isdigits(s);

        do
        {
            if(y != 0)
                  break;

            printf("please reenter the value: ");
            gets(s);
            y = isdigits(s);
        }while(y == 0);
       

        value = atol(s);
        printf("nThe value is: %ldnn",value);
        getch();
    return 0;
}
//------------------------------------------
int isdigits( const char *str )
{
        int i,t,s;
        i = 0;
        t = 1;
        while( str[i]!='' && t==1 )
        {
            s=isdigit( str[i] );
            if(s==0)
                t=0;
            i++;
        }
        if(str[0]=='')
            t=0;
    return t;
}
 

جربوا هذا البرنامج و سترون انه لا يقبل غير اعداد فقط و لكن يجب الحذر لأن لا يكون الرقم المدخل اكبر من 10 خانات و إلا ستكون النتيجة غير صحيحة ;) .

 

_________________________________________________________________________________________________________________________________

آمل أن أكون قد وفقك في إيصال الفكرة لكم و أن تكونوا قد استوعبتموها ...
مع تحياتي ,,,

أخوكم / طلال .

 

 

 


Copyright © www.kettaneh.net