الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

ما هي دالة عكس الكلمة

مغلق
بدأه الحذر في 2 أكتوبر 2005 · 16 رد · 12,008 مشاهدة · في الأسئلة المجابة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم و رحمة الله و بركاته

ابغى اكتي برنامج يدخل المستخدم اسمه و من ثم يقوم البرنامج بعكس الاسم.

مثل يدخل المستخدم اسمه

ثم يقوم البرنامج nosrep ecin a si dammahoM

طبعا الرنامج يحتوي على اولمر اكثر من كذا

انا عملت البرنامج مبديء

بس المشكلة مني عارف ايش هي الدالة

و لكم جزيل الشكر

و السلا م عليكم و حمة الله و بركاته

I_can_always_make_you_smile_by_Praerion.jpg

#2

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

كل ما تحتاجه هو عنوان المصفوفة array اللتي تحتوي على النص, و حجم هذه المصفوفة.

ببساطة, اطبع حروف المصفوفة حرفا حرفا, و لكن ابدأ من نهاية المصفوفة و اذهب الى بدايتها. هذه الطريقة سوف تكتب الكلمة بطريقة معكوسة .. لكنها لن تعكس الكلمة, اذا اردت عكس الكلمة فالعملية مشابهة جدا, فقط قم بإنشاء مصفوفة جديدة بنفس الحجم ثم قم بنسخ حروف المصفوفة بالعكس (ايضا ابدأ من النهاية ثم تحرك للبداية)

void printReversed( char str[], int size )
{
    for( int i = size-1; i >= 0; i-- )
    {
        cout << str;
    }
    cout << endl;
}
int main()
{
    printReversed( "hello", 5 );
    return 0;
}

هو في الحقيقة لا تحتاج بالضرورة الى تحديد الحجم, لانه يمكن ايجاده عن طريق البحث عن الحرف '0\' و لكن في هذا المثال حددت الحجم بمتغير منفصل من أجل السهولة.

تم تعديل هذه المشاركة بواسطة hasan_aljudy في 3 أكتوبر 2005 في 01:01

#3

مثال جيد جدا

بس يوجد دالة جاهزة تسمى strrev تحتاج بارمتر واحد وهو اسم المتغير المراد تحويل القيمة التى بداخلة

انظر المثال :

# include "stdio.h"
# include "conio.h"
#include "string.h"

void main ()
{
char name;
printf("enter your name :");
gets(name);
strrev(name);

printf("your name: %d ",name);

getch();
{

المتغير name سيتم قراته وسيحوى الكلمة المدخلة من المستخدم

ثم نستخدم الدالة strrev واستدعاء المتغير الذى يحوى القيمة المراد عكس الحروف بتاعتها

ثم نقوم بطباعة اللقيمة المتغير عن طريق الامر printf

_____________________________

C Language && Windwos_API

_____________________________

#4

hasan_aljudy :) من الخطأ أن تكتب برنامج مثل هذا فقط لأنه أسهل .. التعامل في السي والسي++ مع الstring جدا حساس ويمكن أن يؤدي إلى العديد من buffer overrun وخرب الstack بغض النظر عن الأمور البهلوانية التي سوف تتلقاها من البرنامج :)

فقط حبيت التنبيه للأخوة .

Coding on the Cloud and for the Cloud!

My Blog

#5

ممكن توضح أكتر يا هانى ؟؟

Muhammad Allam

Computer Science

@Resource(MappedURL="My Blog" )

#6

هاني يقصد : استخدام عمليات معالجة الاخطاء Exception Handle و كما تري المستخدم يدخل مصفوفة و عليها حلقة احتمال كبير بحدوث عملية طفح over flow للمصفوفة ...إلخ من اخطاء المؤشرات

BEng , Electronics and communications.

Embedded systems engineer.

Graphics Programmer

عالم الكومبيوتر هو من لديه المعرفة في علوم الكومبيوتر ، الرياضيات ، هندسة الالكترونيات -احمد صالح

#7
هاني الأتاسي كتب:
hasan_aljudy  :) من الخطأ أن تكتب برنامج مثل هذا فقط لأنه أسهل .. التعامل في السي والسي++ مع الstring جدا حساس ويمكن أن يؤدي إلى العديد من buffer overrun وخرب الstack بغض النظر عن الأمور البهلوانية التي سوف تتلقاها من البرنامج :)

فقط حبيت التنبيه للأخوة .

المشكلة ليست في الضرورة في الكود اللذي يتعامل مع الـ string بل في طريقة اعداد الـ string

هذا الكود مثلا لا يستخدم سوى الـ standard functions و مع ذلك فيه مشكلة الـ overflow

int main()
{    
    char x[] = "Hello";
    strcpy( x, "Test string" );
    cout << x << endl;    
    return 0;
}

المشكلة الحقيقية ان المصفوفات في السي بلص بلص مجرد مؤشرات لا تحتوي اي معلومات عن حجم المصفوفة.

في مثال عكس الجملة, قام الـ function باستلام حجم المصفوفة كمتغير منفصل, و لم يعتمد على الـ strlen .. و لكن لا يوجد اي ضمان في كلا الحالتين ان النتيجة ستكون صحيحة.

الطريقة الأمثل ربما هي استخدام std::string بدلا من []char لتمثيل النصوص .. و لكن من خبرتي الشخصية فإن التعامل مع الـ std::string يجلب الكثير من وجع الراس! قارنه مثلا بالـ String في جافا -- فرق لا يصدق!

#8

أخ أحمد وحسان كلام جميل :) لكن أنا كل قصدي أبسطة من هذا بكثير ..

التابع الذي كتبه حسان ممكن أن يطبع قيم خاطئة إذا كان طول السلسة الممرر إلى التابع أكبر من طول السلسلة نفسها .. يفضل اهمال البارامتر الثاني size في الحل ..

// Method 1 uses recursive, but could result in stack overflow
// ... if the string is formated wrong and is not null terminated

void printReversedRecurs(char *str) {
   if (*str == '\0') return;
   printReversed(str + 1);
   cout << str;
}

void printReversed(char *str) {
   if (!str) return;	// or throw an exception
   printReversedRecurs(str);
   cout << endl;
}

// Method 2 uses strlen to find the end of the string

void printReversed(char *str) {
   if (!str) return;	// or throw an exception
   char *p = str + strlen(str) - 1;
   while (p >= str)
      cout << *p--;
   cout << endl;
}

الطريقة الأولى التي ذكرتها لا يفضل استخدامها وقد تأدي إلى stack overflow إذا كانت السلسلة لا تنتهي بnull character وكانت طويلة جدا! لذلك لا يفضل استخدامها ووضعتها فقط للتوضيح ..

تم تعديل هذه المشاركة بواسطة هاني الأتاسي في 5 أكتوبر 2005 في 09:45

Coding on the Cloud and for the Cloud!

My Blog

#9

ما كل هذا البرنامج بسيط وسهل

اخى الحذر اليك الحل السهل وهذه هى الدالة

# include "stdio.h"
# include "conio.h"
#include "string.h"

void main ()
{
clrscr();
char name[200];
printf("enter your name :");
gets(name);
strrev(name);

printf("your name: %s",name);

getch();
}

الدالة strrev لها بارمتر واحد وهو اسم المتغير الذى يحوى القيمة المراد عكس حروفها

العملية بسيطة انتو ليه ضخمتو الموضوع

تم تعديل هذه المشاركة بواسطة hamada hassan ali في 5 أكتوبر 2005 في 13:55

_____________________________

C Language && Windwos_API

_____________________________

#10

نفس الشي اخي هاني .. لا يوجد اي ضمان إطلاقا بأن الـ null terminator سيكون ضمن حدود المصفوفة و ليس خارجها!

#11

السلام عليكم

هذا الكود يطبع الجملة المدخلة معكوسة ، بشرط أن تنتهي بنقطة (مثلا) .

#include <stdio.h>
void f()
{
	char c;
	scanf("%c",&c);
	if (c!='.')
	{
  f();
  printf("%c",c);
	}
}
void main()
{
	printf("Enter a Sentence : ");
	f();
	printf("\n");
}

MPSI/MP* - CPR Tanger

#12

اخي حسان ، نعم انا معاك وهذه ليس لها حل إلا باستخدام كلاس ال std:string .أو باستخدام بعض الميزات الموجودة في Visual C++ 2005 وأيضا في 2003. ولكن أنا أتكلم بشكل عام فاحتمال خطأ البرنامج في حالة أن الstring ليس لها نهاية احتمال ضعيف إذا استعملت توابع صحيحة لل string .. لكن في حالة وضعك بارامتر ثاني للطول فإنك تزيد احتمال الخطأ.

كل الذي أنوه عليه هو good programming practices in C ..

عليك بهذه المقالة : http://msdn.microsoft.com/msdnmag/issues/0...dC/default.aspx

تم تعديل هذه المشاركة بواسطة هاني الأتاسي في 5 أكتوبر 2005 في 17:08

Coding on the Cloud and for the Cloud!

My Blog

#13

حسن حسن .. و الله حسن مش حسااااان! :( :lol:

انا اصلا وضعت الطول كبارامتر للدالة لكي اتنصل من المسؤلية عن أية اخطاء في الاوفر فلو .. يعني اذا صار خطأ فهذا ليس مسؤولية الدالة بل مسؤولية الشخص اللذي اوصل معلومات خاطئة للدالة.

شخصيا لا اعتقد ان المشكلة في الكود .. المشكلة في اللغة نفسها! لو كان هناك متغير صغير فقط في رأس المصفوفة يخبرك بطولها لانحلت الكثير من المشاكل في السي ..

الـ std::string اصل هو حل لمشكلة لم يكن من المفروض ان توجد من الأساس .. و الحل اللذي يوفره هذا الكلاس برأيي معقد و منتفخ على لا شيء.

اقتباس
ولكن أنا أتكلم بشكل عام فاحتمال خطأ البرنامج في حالة أن الstring ليس لها نهاية احتمال ضعيف إذا استعملت توابع صحيحة لل string .. لكن في حالة وضعك بارامتر ثاني للطول فإنك تزيد احتمال الخطأ.

افضل ان لا احول الموضوع الى جدل .. و لكني لا أرى اي زيادة لاحتمالات الخطأ, فطريقة ارسال الطول كبارامتر منفصل لا تفرق كثيرا عن البحث عن الصفر في نهاية المصفوفة .. و هذا ذكرته سابقا. و وضعت ايضا مثالا على ان الشخص ممكن يحصل على فيض حتى لو استخدم الدوال القياسية. و في تلك الحالة, لن يهم فيما اذا كان الطول مرسل كبارامتر منفصل او يتم البحث عنه بالطرق التقليدية مثل strlen

#14

انا والله ما عمري جربت السي ولا فتحته :D

بس اسمحوا لي أبجرب حل الكود بالفيجوال بيسك يمكن تنفع :rolleyes:

أو على الأقل يمكن فيه دوال تتشابه فتعدل وتبدل بنفسك ..

Dim x, i, t
x = ""
t = ""
For i = Len(Text1.Text) To 1 Step -1
 x = Mid(Text1.Text, i, 1)
 t = t & x
Next
Text2.Text = t

يمكن لعل وعسى وليت ان فيه دوال تتشابه معها :)

مع اني ما اتوقع ..

لكن لا يواخذني صاحب الموضوع ..

وشكراً لكم .

#15

لا اعرف ما كل هذا الذى تتحدثون فيه انتم تحبون الجدام وخلاص انا قاتلكم كذا مرة الكود يمكن استخدام الدالة STRREV فهى دالة قياسية فى السى يعنى تعمل مع اى مترجم وهى لمكتبة STRING تقوم بالتصريح عن متغير نصى X

ثم نقراء قيمة من المستخدم عبر هذا المتغير X سيتم تسجيل القيمة بداخله كمثل AHMED ثم نقوم بأخذ الدالة STRREV ونضع اسم المتغير كبارمتر للدالة ثم نطبع قيمة المتغير X

النتيجة :

الاسم AHMED سيتحول الى DEMHA

لماذا كل هذا اللف والدوران

اقتباس
شخصيا لا اعتقد ان المشكلة في الكود .. المشكلة في اللغة نفسها! لو كان هناك متغير صغير فقط في رأس المصفوفة يخبرك بطولها لانحلت الكثير من المشاكل في السي ..

اخى المشكلة ليست فى اللغة المشكلة هى فى عدم معرفة الدالة STRREV الذى هى وظيفتها الاساسية عكس حروف الكلمات الذى هو اصلاا محور الموضوع والجدل

عندكم دالة جاهزة وتفكرون فى حلها بالمصوفات

لا اعرف لماذا

تم تعديل هذه المشاركة بواسطة hamada hassan ali في 5 أكتوبر 2005 في 20:32

_____________________________

C Language && Windwos_API

_____________________________

#16

نحن لا ننتناقش في صحة الحل .. بل في مدى أمانه و فاعليته.

للذين لم يفهموا النقاش اللذي جرى بيننا, أحب ان اوضح شيئا عن النصوص و المصفوفات في السي و السي بلص بلص.

المصفوفات في لغة السي عبارة عن مساحة متواصلة من الذاكرة محجوزة لغرض معين, و المتغير اللذي تستخدمه في التعامل مع المصفوفة هو في الحقيقة مجرد مؤشر لبداية المصفوفة (اول عنصر فيها, و هو العنصر رقم 0).

عندما تحجز مصفوفة طولها عشر عناصر, فان البرنامج يقوم من تحت الستار بحجز مساحة من الذاكرة تكفي لعشر عناصر (يعني لو كان كل عنصر ياخذ 4 بايت, و حجزت عشر عناصر, فان البرنامج سيقوم بحجز 40 بايت من الذاكرة من اجل تلك المصفوفة).

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

ممكن جدا ان تحجز مصفوفة طولها خمس عناصر .. ثم يقوم الكود بعمل التالي:

غير العنصر الأول الى القيمة 3

غير العنصر الثاني الى القيمة 5

غير العنصر السابع الى القيمة 12

لحظة لحظة .. اي عنصر سابع تتحدث عنه؟ المصفوفة بها خمس عناصر فقط! ما هو العنصر السابع؟

حسنا .. العنصر السابع هو ببساطة مكان في الذاكرة يقع بعد العنصر الأول بمسافة ست عناصر!!!

يعين فعليا تستطيع ان تكتب على مساحات من الذاكرة غير مخصصة للمصفوفة, و لا يوجد شيء في اللغة يمنعك من ذلك او على الأقل ينبهك عليه.

ممكن جدا ان تكون المساحة اللتي تكتب عليها هي مساحة حساسة اذا كتبت عليها ستخربط البرنامج, و هذا يحصل كثيرا خصوصا عندما تحصل هذه المشكلة على الـ stack

اذا حجزت مصفوفة ذات سبع عناصر مثلا بهذه الطريقة:

int[7] x;

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

هذه المشكلة اسمها buffer overflow

بالمناسبة .. النصوص في السي و السي بلص بلص عبارة عن مصفوفة من الحروف, لا أكثر ولا أقل.

#17

يمكن أن تستخدم الstring القياسي الموجود في الملف string.h فهو عبارة عن class يوجد فيه كل ماتحتاجه من معلومات كما أنه يحتوي على الoperator [ ] و مُجهز للتعامل مع الout of array boundry بحيث لا يسمح لك بتجاوز حدود الstring

Sr. Software Development Engineer
Hulu, LLC
My Blogs

هذا الموضوع مغلق.

مواضيع مشابهة