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

[ تمت الإجابة ]سؤال : محاكاة محرر نصوص

بدأه m1m6 في 7 ديسمبر 2012 · 18 رد · 870 مشاهدة · في الأسئلة المجابة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم

عندي مشكلة في ادخال كاراكترز

هذا كود البرنامج بالكامل

//file LE.h

struct nodetype;
const int SIZE=81;
typedef char dataline[81];
typedef nodetype *nodeptr;

class LED
{
public:
	LED();
	~LED();
	void insert(dataline lines);
	void Delete();//delete currnt line 
	void move(int num);
	int cnt();// To Find Number Of Nodes.
	void list();
	void EXIT();



private:
	nodeptr head;
	nodeptr current;

};

//file LE.cpp

#include"LE.h"
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cmath>

using namespace std;

struct nodetype
{
char data[SIZE];
nodeptr link;
};


LED::LED()
{
head=NULL;
current=NULL;
}
LED::~LED()
{
nodeptr delptr;
while(head!=NULL)
{
delptr=head;
head=head->link;
delete delptr;

}
}

void LED::insert(dataline lines)

{
	nodeptr newptr=new nodetype;
        newptr->link=NULL;

	for(int i=0;i<SIZE;i++)
		newptr->data=lines;

	if(current != NULL)

{ 
	nodeptr ptr=head;
	while(ptr->link!=current)
	ptr=ptr->link;
	newptr->link=ptr->link;
	ptr->link=newptr;


}


	else if(head==NULL)
	{
	    head=newptr;	    
	}
	else
	{
            nodeptr cur = head;
            while( cur->link )
				cur= cur->link;
	    cur->link=newptr;
	}




}

void LED::list()
{
	nodeptr put=current;
	if(current==NULL)
		cout<<"<<END>>\n";

	else{
	while(put!=NULL)
	{

		cout<<put->data<<endl;
		put=put->link;
	}
	    }
}

int LED::cnt()
{
nodeptr temp=head;
int c=0;
if(head==NULL)
	return 0;
else
	c++;
while(temp->link!=NULL)
{
c++;
temp=temp->link;

}
return c;


}
void LED::move(int num)
{	nodeptr ptrMove;
	//current=NULL;
	ptrMove=head;
	int mMove;

	int funX;


	if(num<0)
	{

	funX=cnt()+num+1;//just for minus

	mMove=abs(num);//for minus

	if(mMove>cnt())
	{
		current=head;
		cout<<current->data<<endl;
	}
	else if(mMove<=cnt())

	{

		for(int i=1;i<funX;i++)
		{
			ptrMove=ptrMove->link;
		}
		current=ptrMove;
		cout<<current->data<<endl;

	}

	}


	else if(num>cnt())
	{
	current=NULL;
	cout<<"<<END>>  "<<endl;
	}
	else 
	{

		if (current==NULL)
			cout<<"<<END>>"<<endl;
		else
		{
		current=current->link;
		cout<<current->data<<endl;
		}
	}

}

void LED::EXIT()
{
exit(1);
}

void LED::Delete()
{
nodeptr Delt;
if(current==head)
{
	head=head->link;
}
Delt=current;
current=current->link;
delete Delt;
}



//client file


#include<iostream>
#include<cstdlib>
#include<cstddef>
#include"LE.h"
#include<string>
#include<cmath>

using namespace std;
int main()
{
	cout<<"###############################################################################\n";
	cout<<"#  Line Editor \n";
	cout<<"#  Please Use these commands (IN,DL,MV,LI,EX). \n";
	cout<<"#  command (IN) To Insert A New Line,should be followed by tow slashes (//). \n";
	cout<<"#  Command (LA) To list All Lines.\n";
	cout<<"#  Command (MV) Should Be Followed By Integer In The Same Line.\n";
	cout<<"#  Command (DL) To Delete The Current Line.\n";
	cout<<"#  Command (XT) To Terminate The Program.\n";
	cout<<"###############################################################################\n";
LED l1;	
int movment;
string input;
dataline line;

cout<<">";
cin>>input;

while(input!="XT")
{

	if (input=="IN")
	{
		cin.getline(line,SIZE);
		while(line[0]!='/'&&line[1]!='/'&&line[3]!='\0')
		{
			l1.insert(line);
		cin.getline(line,SIZE);
		}

	}
	else if(input=="LA")
		l1.list();
	else if(input=="DL")
		l1.Delete();
	else if(input=="MV")
	{	cin>>movment;
		l1.move(movment);
	}
	else if(input=="XT")
		l1.EXIT();
	else
		cout<<"Error Command...!"<<endl;
	cout<<">";
	cin>>input;

}
cout<<l1.cnt()<<endl;


system("pause");
return 0;
}



// المشكلة تبدا هنا 

	if (input=="IN")
	{
		cin.getline(line,SIZE);
		while(line[0]!='/'&&line[1]!='/'&&line[3]!='\0')
		{
			l1.insert(line);
		cin.getline(line,SIZE);
		}

فــ مثلا انا لو اردت ادخال سطرين من المدخلات مثل

1111 1111 1111 111

2222 22222 2222

//

ووضعت بعد الادخال //

المفروض انه يضيف في اللست two nodes

لكنه بيحسب الــ // على انه نص وبيضيفها داخل اللست

كيف اخليه ما يدخل الـ // لداخل اللست ؟

#2
اقتباس
لكنه بيحسب الــ // على انه نص وبيضيفها داخل اللست

على العكس, البرنامج لا يقوم حتى بإدراج المُدخلات داخل القائمة :

post-219439-019930500 1354868753_thumb.p
المرفقات
OutPut.png
#3

لا اخي بيدخلها

لكن عمل البرنامج

انو عندي بوينر اسمو current

الان جرب الامر mv -2 مثلا

ادخل بالبداية اي عدد سالب

البوينر كرنت راح يطبعلك النود حسب العدد اللي انت ادخلته

وجرب بعدها الامر LA

راحد يطبع جميع النود بداية من البوينر كرنت وحتى نهاية اللست

  nodeptr put=current;
        if(current==NULL)
                cout<<"<<END>>\n";

        else{
        while(put!=NULL)
        {

                cout<<put->data<<endl;
                put=put->link;
        }
            }

//  طبعا اول ما ادخلت LA ظهر لك النهاية لان بوينر كرنت يؤشر على النل....

  nodeptr put=current;
        if(current==NULL)
                cout<<"<<END>>\n";
#4

بداية, أنت تستخدم قائمة تحتوي على مصفوفة حرفية و بالتالي عند التعامل مع مصفوفة المحارف يُستحسن استخدام الدوال الموجودة في الملف string.h.

استبدل هذه الفقرة :

for(int i=0;i<SIZE;i++)
newptr->data=lines;

بــ

strcpy(lines,newptr->data);

و هذا الشرط :

line[0]!='/'&&line[1]!='/'&&line[3]!='\0'

بــ :

strcmp(line,"//")

بالنسبة للدالة move هل تحتاج إليها لكي تنجح عملية الــ Insertion ؟

1
#5

مشكور اخوي على ردك

المشكلة الان صار يضيف لي نود ولكنها فارغة

شوف هذي المدخلات مثلا

>IN
11 1111
2222222
//
>LA
<<END>>
>MV -2
11 1111 
>XT
3// هذا يخرج لي عدد النود

النود الثالثة ما تحتوي على اي نص ولكنها فارغة .....

الدالة MOVE ليس لها علاقة بالادخال

هي بس عشان احرك البوينتر كرنت لقيمة يدخلها المستخدم

مثلا انا بدي يظهر لي السطر الرابع في اللست

MV -4

وهكذا....

الان المشكلة بقيت في النود الثالثة :)

#6

ما هذا يا أخي الكريم ؟

void LED::insert(dataline lines) {
    nodeptr newptr = new nodetype;
    newptr->link = NULL;

    for (int i = 0; i < SIZE; i++)
        newptr->data = lines;

    if (current != NULL) {
        nodeptr ptr = head;
        while (ptr->link != current)
            ptr = ptr->link;
        newptr->link = ptr->link;
        ptr->link = newptr;
    } else if (head == NULL) {
        head = newptr;
    } else {
        nodeptr cur = head;
        while (cur->link)
            cur = cur->link;
        cur->link = newptr;
    }
}

كل هذه السطور من أجل إضافة عقدة واحدة إلى قائمة متصلة و غير مزدوجة ؟؟

كيف يا أخي ؟ :)

اقتباس
الدالة MOVE ليس لها علاقة بالادخال

هي بس عشان احرك البوينتر كرنت لقيمة يدخلها المستخدم

أعتقد أنه لا داعي لهذه الدالة لأن مجرد تحريك الــ Pointer لا فائدة فيه إلا إذا كان الأمر من باب "التحقق" من عناصر القائمة.

1
#7

:)

اخي السؤال مطلوب منه كالتالي

اولا البرنامج هو line editor

محرر اسطر :blink:

ادخال بيانات على شكل اسطر

وعندنا بوينتر الكرنت وهذا البوينتر هو اللي راح يتحكم بكل البرنامج

بالبداية هذا النود يأشر على قيمة نول

واسطتيع تغيير مكان الكرنت عن طريق الدالة MOVE

تخيل انه البوينتر كرنت موجود في اخر اللست ويؤشر على القيمة نول

CURRENT

HEAD ->11111 -> 222 ->NULL

الان لو ادخلت امر

MV -2

البوينتر كرنت راح يتحرك الى اليسار خطوتين

يعني راح يصير يأشر على اول نود وهي 11111111

ولو دخلت MV 1

راح يتحرك لليمين خطوة

يعني يصير يأشر على النود 22222222222

اما اذا دخلت رقم اكبر من عدد النود راح يأشر اما على النول او على اول نود حسب اشارة العدد اذا كان سالب او موجب

وايضا لما بدي اضيف مدخلات جديدة لازم تكون قبل البوينتر كرنت

مثلا عندي اللست على هذا الشكل

والبوينتر كرنت يؤشر على النود الثانية

CURRENT

HEAD ->11111 -> 222 ->NULL

ولنفترض اني بدي ادخل المدخلات التالية

3333333333333

44444444444

//

راح يصير شكل النود هيك

CURRENT

HEAD ->11111 ->33333333->444444444-> 222 ->NULL

يعني الاضافة لازم انها تكون قبل النود اللي بيأشر عليها الكرنت

ولما بدي احذف DL

راح يحذف النود اللي بيأشر عليها الكرنت , وبوينتر الكرنت راح يتقدم خطوة ...... :)

CURRENT

HEAD ->11111 ->33333333->444444444 ->NULL

المشكلة الان في الادخال اخي

	cin.getline(line,SIZE);
		while(strcmp(line,"//"))
		{
			l1.insert(line);
		cin.getline(line,SIZE);
		}

:)

بخصوص الدالة INSERT

الاكواد كثيرة فيها

والسبب هذا

 if (current != NULL)

لانو حسب طلب السؤال اذا كان البوينتر كرنت لا يساوي نول

فـــ الاضافة لازم تكون قبله...........

#8
اقتباس
حسب طلب السؤال اذا كان البوينتر كرنت لا يساوي نول فالاضافة لازم تكون قبله

أفهم من هذا أنه إذا كان الــ Current Pointer يُساوي NULL فستتم الإضافة بعده و هذا ما جعل دالة الإظهار تُظهر دائما END لأن شرط التوقف يتحقق عند أول عُقدة و بالتالي سيتم تجاهل العُقد الموجودة بعد العقدة الفارغة :)

1
#9

الأخ الكريم

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

مرحباً بكم في منتدى الفريق العربي للبرمجة

نود تنبيهك أن العنوان غير مناسب.

الرجاء اختيار عنوان مناسب أكثر في مواضيعك القادمة، وهذا بمثابة إشعار للأهمية.

وفي حال التكرار سيتعرض موضوعك للإغلاق والحذف !

قواعد المشاركة

شاكرين لكم حُسن تعاونكم

1
#10

العكس

تخيل انو الكرنت موجود في اخر اللست وقيمته نول

Ier88639.jpg

تخيل ,, ولكن في الحقيقة الكرنت قيمته صفر

طول ما انا بـعمل ادخال في البيانات عند اول تشغيل للبرنامج والكرنت قيمته صفر

لكن بمجرد اني استخدم الامر MV الكرنت راح يتغير مكانه

حسب الرقم اللي ادخله اليوزر

>IN             // الكرنت قيمته صفر
11 1111                  // الكرنت قيمته صفر
2222222                         // الكرنت قيمته صفر
//
>LA                              // الكرنت قيمته صفر
<<END>>                             
>MV -2                        // الان البوينتر الكرنت بيصير يأشر على اول نود .......
11 1111 
>IN
333333
44444
//
>LA
1111 11
2222222
3333333
44444

اتمنى توضحت لك الفكرة ... :)

تم تعديل هذه المشاركة بواسطة m1m6 في 7 ديسمبر 2012 في 16:27

#11

مشكلة النود الأخيرة بسيطة جداً :)

السبب يعود إلى أنك تزيد قيمة c مرتين, الأولى قبل دخول while و الثانية عند الدخول مباشرة.

تصحيح الدالة cnt :

int LED::cnt() {
    nodeptr temp = head;
    int c = 0;
    if (head == NULL) return 0;
    do {
        c++;
        temp = temp->link;
    } while (temp->link != NULL);
    return c;
}
#12

عدلت الدالة cnt

لكن المشكلة ضلت في الادخال

هذا نص السؤال

dHH95658.jpg

wYM95697.jpg

kou95746.jpg

wfe95779.jpg

#13

شوف اخوي

هذا تراسينغ شوف وين المشكلة

>IN
111111111
22222222
//
>MV -2
111111111saleb < cnt()
>MV 1
22222222mojb <cnt
>LA
22222222
>IN
33333
44444
//
>LA
22222222
>MV -100
HHHHHH
>LA
                                             // هذا نود فاضي ويطبعه....
111111111
                                              //   هذا نود فاضي ويطبعه.... هنا المشكلة 
33333
44444
22222222
>XT
6
#14
اقتباس
عدلت الدالة cnt لكن المشكلة ضلت في الادخال

حتى لا تختلط الأمور, تعديل الدالة cnt يتعلق بإصلاح الطول الحقيقي للقائمة و لا علاقة له بالإدخال :)

بالنسبة لمشكلة الإدخال فيُمكنك عدم إظهار العناصر الفارغة من خلال التحقق قبل إجراء عملية الإخراج, هكذا :

if(strcmp(put->data,"") != 0)
#15

تسلم اخوي

لكن المشكلة لا تكمن في عملية الاخراج

وانما الــ "" تحتسب كـــ نود

وبالتالي لو ضفت

1111111

222222222

//

راح يظهر لي عدد النود = 3

وبالتالي راح يأثر على الدالة MV

خطر في بالي حل

انو اعرف كاراكتر جديد

char ch;

واضيفه بعد عملية الادخال لحتى ما يحسب الــ سطر الجديد كـــ نود

char ch;

while(input!="XT")
{

	if (input=="IN")
	{

		do{
		cin.get(line,SIZE);
		cin.get(ch);
		if(line[0]=='/'&&line[1]=='/')
			break;
		l1.insert(line);
		}while(cin);
	}

لكنها بقت مشكلة

اتمنى حلها

وبارك الله فيك على جهودك اخوي :)

#16

لتجاهل المُدخلات استخدم التابع ignore.

ignore يستقبل معاملين, المعامل الأول يمثل أكبر عدد من الأحرف الذي يمكن تجاهله أما المعامل الثاني فيمثل متغير حرفي يمثل حرف تحديد النهاية.

مثال :

cin.ignore(10,'m');

لكن المشكلة ليست في الإدخال على الإطلاق و إنما يوجد خطأ منطقي في إحدى دوالك.

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

بالتوفيق.

#17

بارك الله فيك اخوي

تم حل المشكلة

المشكلة كانت في عملية الادخال

وعرفت متغير جديد من نوع كاراكتر

والله يوفقك :)

#18

يُمكنك أن تضع حل مشكلة الإدخال هنا في الموضوع ليستفيد غيرك.

بالتوفيق.

#19
	if (input=="IN")
	{
		cin.get(ch);
		cin.get(line,SIZE);
	do{
	if(line[0] == '/' && line[1] == '/')
	break;
	l1.insert(line);
	cin.get(ch);
	}while(cin.get(line, SIZE));
	}

حل مشكلة الادخال :)

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