PDA

View Full Version : مبتدی: تعريف آرايه ی پويا از رشته ها و دستکاری رشته



D_felfelak
سه شنبه 19 دی 1391, 13:13 عصر
دارم روی پروژه ی دانشگاه کار ميکنم ترم اول علوم کامپيوتر هست و هيچ آشنايی با شی گرايی ندارم
پروژه يه سيستم مديريت نمرات دانشجو هست با قابليات متفاوت!
سؤال:
تا حالا آرايه ی پويا و آرايه از رشته رو ديدم
اما نميدونم چطور ميشه آرايه ی پويا از رشته تعريف کرد؟!
پويا باشه تا طولش رو در برنامه و هنگام کار باهاش تغيير بدم
ميخوام نام و نام خانوداگی رو اعتبار سنجی کنم که مثلا" آيا حرف اولش کوچک هست ؟ آيا تمام حروف کوچيک هست يا نه؟
برای اينکار بايد به تک تک کاراکتر های هر درايه ی آرايه که خودش رشته است دسترسی داشته باشم!
مشکلم سر اين دسترسی هست!

sohil_ww
سه شنبه 19 دی 1391, 13:21 عصر
برای آرایه های پویا باید از اشاره گر ها استفاده کنی ! که مطالبی آموزشی زیادی تو دنیای نت موجوده !

قسمت 2:متوجه مشکلت نشدم !

D_felfelak
سه شنبه 19 دی 1391, 14:00 عصر
برای آرایه های پویا باید از اشاره گر ها استفاده کنی ! که مطالبی آموزشی زیادی تو دنیای نت موجوده !

قسمت 2:متوجه مشکلت نشدم !
اشاره گر خوندم
مثلا" آرايه ی پويا:
int *x;
int n;
x = new int [n ]

آرايه از رشته:

string s[5];
اما نميدونم چطور آرايه پويا از رشته تعريف کنم!
مثلا" شما ميخوايد رشته واقع در درايه ی اول يک آرايه ی پويا رو تغيير بدين بذارين c
چه دستوری ميدين؟

D_felfelak
چهارشنبه 20 دی 1391, 00:40 صبح
آرايه ی پويا از رشته رو بصورت زير تعريف کردم:




#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;

void meno( string *name, string *lase_name, float *ave , int *number );
void add ( string *name, string *lase_name, float *ave , int *number );
void sort ( string *name, string *lase_name, float *ave , int *number );
int i = 1;

int main()
{
bool ans = true;
float *Ave;
int *number;
string *name;
string *lase_name;
Ave = new float[i];
number = new int[i];
name = new string[i];
lase_name = new string[i];
while (ans)
{
meno( name, lase_name, Ave , number );
cout << "Do you want continue? (true or false) " << "\n";
cin >> ans;
}
cin.get ();
cin.get();
return 0;
}

void meno ( string *name, string *lase_name, float *Ave, int *number )
{
int ans;
cout << "\n";
cout << "Your welcome manager :" << "\n\n"
<<setw (7) << "meno" << "\n"
<< setw (7) << "Add" << "\t" << "1" << "\n"
<< setw (7) << "Sort" << "\t" << "2" << "\n"
<< setw (7) << "Edit" << "\t" << "3" << "\n"
<< setw (7) << "Grade G" << "\t" << "4" << "\n"
<< setw (7) << "Maximum" << "\t" << "5" << "\n"
<< setw (7) << "minimum" << "\t" << "6" << "\n\n"
<< "enter a number" << "\n";
cin >> ans;
switch (ans)
{
case 1:
add ( name, lase_name, Ave , number );
break;
case 2:
sort ( name, lase_name, Ave , number );
break;
default:
cout << "entered number is not Definition: " << "\a\n";
meno( name, lase_name, Ave , number );
break;
}
cin.get();
}

void add ( string *name, string *lase_name, float *Ave , int *number )
{
cout << "student \t" << i << "\n" ;
cout << "Enter a number : ( if after enter: -1 ) " << "\n";
cin >> *(number + i);
cout << "Enter a Average : ( if after enter: -1 ) " << "\n";
cin >> *(Ave + i);
cout << "Enter a name: ( if after enter: -1 ) " << "\n";
cin >> *(name + i);
cout << "Enter a last name: ( if after enter: -1 ) " << "\n";
cin >> *(lase_name + i);
i++;
}




آرايه ی پويا از رشته رو بصورت بالا تعريف کردم:
بعد از نمايش منو 1 رو ميزنم تا وارد add بشه
برای دريافت معدل و شماره دانشجويی مشکل نداره
اما وقتی نام رو ميزنم برنامه اصلا" درست کار نميکنه؟
مشکل از کجاست؟!
با تشکر از پاسخ گويی شما

lexical_error
پنج شنبه 21 دی 1391, 16:14 عصر
سلام
دوست عزیز شما مقداری که برای تعداد خانه های آرایه هایی که رو حافظه آزاد تعریف شده اند رو 1 در نظر گرفتید،و این به این معنی هست که آرایه فقط 1 خانه از حافظه رو رزرو میکنه و اون هم افست 0 هست.
و اگر شما تلاش کنید که به خانه های بعد از مقدار مشخص شده دسترسی پیدا کنید برنامه دچار خطا میشود!
برای این کار نیازی به ایجاد آرایه نیست!!
آرایه رو هم معمولا زمانی به صورت پویا تعریف میکنند که قرار باشه کاربر تعداد خانه های مورد نیاز آرایه رو وارد کنه یا طول آرایه در حین اجرای برنامه دچار تغییر بشه!
آرایه از نوع string هم به این معنی هست که هرکدام از خانه های آرایه توانایی نگه داری string رو دارند، اگر نوع آرایه از نوع char بود اون موقع نیاز به ایجاد آرایه ای از کاراکترها بود...

در ضمن همیشه سعی کنید متغییر یا آرایه هایی که روی حافظه آزاد ایجاد میکنید با دستور delete آزاد کنید ، چون خود به خود از حافظه حذف نمیشوند و باعث نشت حافظه میشوند!!

قبل از retrun تابع main اضافه کنید
delete [] ave;
delete [] number;
delete [] name;
delete [] lase_name;

D_felfelak
پنج شنبه 21 دی 1391, 20:01 عصر
سلام
دوست عزیز شما مقداری که برای تعداد خانه های آرایه هایی که رو حافظه آزاد تعریف شده اند رو 1 در نظر گرفتید،و این به این معنی هست که آرایه فقط 1 خانه از حافظه رو رزرو میکنه و اون هم افست 0 هست.
و اگر شما تلاش کنید که به خانه های بعد از مقدار مشخص شده دسترسی پیدا کنید برنامه دچار خطا میشود!
برای این کار نیازی به ایجاد آرایه نیست!!
آرایه رو هم معمولا زمانی به صورت پویا تعریف میکنند که قرار باشه کاربر تعداد خانه های مورد نیاز آرایه رو وارد کنه یا طول آرایه در حین اجرای برنامه دچار تغییر بشه!
آرایه از نوع string هم به این معنی هست که هرکدام از خانه های آرایه توانایی نگه داری string رو دارند، اگر نوع آرایه از نوع char بود اون موقع نیاز به ایجاد آرایه ای از کاراکترها بود...

در ضمن همیشه سعی کنید متغییر یا آرایه هایی که روی حافظه آزاد ایجاد میکنید با دستور delete آزاد کنید ، چون خود به خود از حافظه حذف نمیشوند و باعث نشت حافظه میشوند!!

قبل از retrun تابع main اضافه کنید
delete [] ave;
delete [] number;
delete [] name;
delete [] lase_name;
عزيز خب ما نميدونيم که کاربر قرار هست اطلاعات چند تا دانشجو رو وارد کنه!
برای همين آرايه پويا هست و هر بار که کاربر يکی و اد ميکنم طول آرايه های پويا پلاس پلاس ميشه
برای اد کردن شماره دانشجويی و معدل خطا نميده برای نآم و نام خانوادگی که استرينگ هست خطا ميده!
مجاز به استفاده استراکچر نيستيم

lexical_error
پنج شنبه 21 دی 1391, 20:57 عصر
عزيز خب ما نميدونيم که کاربر قرار هست اطلاعات چند تا دانشجو رو وارد کنه!
برای همين آرايه پويا هست و هر بار که کاربر يکی و اد ميکنم طول آرايه های پويا پلاس پلاس ميشه
برای اد کردن شماره دانشجويی و معدل خطا نميده برای نآم و نام خانوادگی که استرينگ هست خطا ميده!
مجاز به استفاده استراکچر نيستيم
خب برای اینکه کاربر تعداد رو وارد کنه شما باید به این صورت آرایه رو تعریف کنید
int x;
string *name;
cout<<"Enter Number Of elements:";
cin>>x;
name = new string[x];

و اینکه در این زبان هیچ تعریفی نیست مبنی بر این که طول آرایه به طور خودکار افزایش پیدا کنه،اگر هم موفق به انجام این کار بشین هنگامی که برنامه به قسمت حذف حافظه آزاد میرسه با خطا مواجه میشین

CRT detected that the application wrote to memory after end of heap buffer.

D_felfelak
جمعه 22 دی 1391, 00:22 صبح
خب برای اینکه کاربر تعداد رو وارد کنه شما باید به این صورت آرایه رو تعریف کنید
int x;
string *name;
cout<<"Enter Number Of elements:";
cin>>x;
name = new string[x];

و اینکه در این زبان هیچ تعریفی نیست مبنی بر این که طول آرایه به طور خودکار افزایش پیدا کنه،اگر هم موفق به انجام این کار بشین هنگامی که برنامه به قسمت حذف حافظه آزاد میرسه با خطا مواجه میشین

CRT detected that the application wrote to memory after end of heap buffer.

آخه استاد گفت که کاربر تعداد رو وارد نميکنه و و از کاربر تعداد رو نميپرسيم و کاربر رو محدود به يه ماکزيمومی نميکنيم
با اين شرايط چه کار کنم؟

mahak006
جمعه 22 دی 1391, 02:42 صبح
آخه استاد گفت که کاربر تعداد رو وارد نميکنه و و از کاربر تعداد رو نميپرسيم و کاربر رو محدود به يه ماکزيمومی نميکنيم
با اين شرايط چه کار کنم؟

با این شرایط باید هر بار که کاربر ، داده ی جدید وارد می کنه ، یه آرایه ی رشته ای جدید با طول پویای یکی بیشتر از قبلی درست کنید ( x++ ) بعد مقادیر موجود تو هر درایه از آرایه ی قبلی رو نظیر به نظیر به آرایه ی جدید منتقل کنید . بعدش آرایه رشته ای قدیمی رو حذف ( delete ) کنید . در آخر کار هم اطلاعات فیلد جدید وارد شده رو در عنصر آخر آرایتون قرار بدین .

mahak006
جمعه 22 دی 1391, 02:50 صبح
http://barnamenevis.org/showthread.php?365437-%DA%A9%D9%85%DA%A9-%D8%AF%D8%B1-%D8%A2%D8%B1%D8%A7%DB%8C%D9%87-%D9%87%D8%A7-%DB%8C-%D8%AF%D8%A7%DB%8C%D9%86%D8%A7%D9%85%DB%8C%DA%A9-%D8%AF%D8%B1-C-%E2%80%8E

این لینک رو یه نگاه بنداز . دقیقا همچین چیزی می خواست . که البته بره اعداد صحیح نیاز داشت . نه رشته . ولی تو عمل زیاد فرق نمی کنن .
فقط یه مشکلی که این جور برنامه ها دارن و یا باید با لیست پیوندی و شیء گرایی نوشتشون ، یا با اون مشکل کنار اومد اینه که هر چی جلو تر می ری و تعداد ورودی ها بیشتر می شه ، به واسطه ی انتقال از آرایه ی قبلی به آرایه ی جدید ، برنامه رفته رفته کند تر می شه و اگه تعداد ورودی ها خیلی زیاد بشه ، این افت سرعت برنامه کاملا محسوسه.

D_felfelak
یک شنبه 01 بهمن 1391, 17:48 عصر
#include "stdafx.h"
#include <iostream>
#include
<iomanip>
#include <string>
using namespace std;


void meno( string *name, string *lase_name, float *ave , int *number
);


void add ( string *name, string *lase_name, float *ave , int *number );

int i = 0;


int main()
{
bool ans = true;
float *Ave;
int
*number;
string *name;
string *lase_name;
Ave =
new float[i];
number = new int[i];
name = new
string[i];
lase_name = new string[i];
while
(ans)
{
meno( name, lase_name, Ave , number
);
cout << "Do you want return meno? (true or false) "
<< "\n";
cin >> ans;
}
// maiel be
chap hasty ya na?!
cin.get ();
cin.get();
return
0;
}


void meno ( string *name, string *lase_name, float *Ave, int *number
)
{
int ans;
cout << "\n";
cout <<
"Your welcome manager :" << "\n\n"
<<setw (7)
<< "meno" << "\n"
<< setw (7) << "Add"
<< "\t" << "1" << "\n"
<<
setw (7) << "Sort" << "\t" << "2" <<
"\n"
<< setw (7) << "Edit" << "\t" << "3"
<< "\n"
<< setw (7) << "Delete" << "\t"
<< "4" << "\n"
<< setw (7) << "Show"
<< "\t" << "5" << "\n"
<< "enter
a number" << "\n";
cin >> ans;
switch
(ans)
{
case 1:
add ( name,
lase_name, Ave , number );
break;
case
2:
sort ( name, lase_name, Ave , number
);
break;
case
3:
menoedit ( name, lase_name, Ave , number
);
break;
case
4:
menodelete ( name , lase_name , Ave , number
);
break;
case
5:
menoshow ( name , lase_name , Ave , number
);
default:
cout << "entered number is
not Definition: " << "\a\n";
main
();
break;
}
cin.get();
}



void add ( string *name, string *lase_name, float *Ave , int
*number )
{
cout << "Your welcome add meno " <<
"\n";
cout << "student: \t" << i << "\n"
;
i++;


int *temp;
temp = new int [i];
for (int j = 0; j <
i-1; j++)
temp [j] = number [j];
cout << "Enter a
number : ( if after enter: -1 ) " << "\n";
cin >> temp
[i];
cin.get();
for (int j = 0; j < i;
j++)
number [j] = temp [j];
delete temp;


float *atemp;
atemp = new float [i];
for (int j = 0;
j < i-1; j++)
atemp [j] = Ave [j];
cout <<
"Enter a Average : ( if after enter: -1 ) " << "\n";
cin >>
atemp [i];
cin.get();
for (int j = 0; j < i;
j++)
Ave [j] = atemp [j];
delete atemp;


string *ntemp;
ntemp = new string [i];
for (int j =
0; j < i-1; j++)
ntemp [j] = name [j];
cout <<
"Enter a name: ( if after enter: -1 ) " << "\n";
cin >>
ntemp [i];
cin.get();
for (int j = 0; j < i;
j++)
name [j] = ntemp [j];
delete
ntemp;

string *lntemp;
lntemp = new string
[i];
for (int j = 0; j < i-1; j++)
lntemp [j] =
lase_name [j];
cout << "Enter a last name: ( if after enter: -1 )
" << "\n";
cin >> lntemp
[i];
cin.get();
for (int j = 0; j < i;
j++)
lase_name [j] = lntemp [j];
delete lntemp;
}

گرامی همين طور که گفتين نوشتم اما باز هم ارور ميده!

چه کار کنم؟


delete ها رو که پاک کردم ارور هنگام وارد کردن شماره دانشجويی و معدل رفتاما هنگام وارد کردن نام و نام خانوادگی باز هم ارور داد!

vahid_fathi
یک شنبه 01 بهمن 1391, 21:48 عصر
داداش من تاپیکی رو کامل نخوندم ولی فک کنم بهتره تو دستورای پایین
string *ntemp;
ntemp = new string [i];
به جای string از char استفاده کنی . شاید کار بکنه . تا جایی که یادمه ما هم از char استفاده میکردیم .
یه نظرم دارم بهتره از delete هم استفاده کنی و برا اینکه چیزایی که تا حالا گرفتی رو از دست ندی بهتره اونا رو تو یه ارایه ی دیگه که استاتیک هستن ذخیره کنی یا میتونی از vector استفاده کنی . برا اینکه قاطی نشن هم میتونی از یه علامت استفاده کنی یا همچین چیزی . موفق باشی .

D_felfelak
دوشنبه 02 بهمن 1391, 09:16 صبح
داداش من تاپیکی رو کامل نخوندم ولی فک کنم بهتره تو دستورای پایین
string *ntemp;
ntemp = new string [i];
به جای string از char استفاده کنی . شاید کار بکنه . تا جایی که یادمه ما هم از char استفاده میکردیم .
یه نظرم دارم بهتره از delete هم استفاده کنی و برا اینکه چیزایی که تا حالا گرفتی رو از دست ندی بهتره اونا رو تو یه ارایه ی دیگه که استاتیک هستن ذخیره کنی یا میتونی از vector استفاده کنی . برا اینکه قاطی نشن هم میتونی از یه علامت استفاده کنی یا همچین چیزی . موفق باشی .
از char نميتونم استفاده کنم چون ميخوام نام و نام خانوادگی ذخيره کنم!

omidshaman
دوشنبه 02 بهمن 1391, 09:52 صبح
این دیگه چه مدل کد نوشتنه

Ave =
new float[i];
return
0
name = new
string[i];
cin >> temp
[i];
!!! فقط می خوای تعداد خط ها بره بالا درسته؟!!
delete هاتم درست نیستن مثلا خط 134 باید باشه چون داری یک ارایه رو پاک می کنی

delete temp[]

omidshaman
دوشنبه 02 بهمن 1391, 10:07 صبح
و یک نکته دیگه وقتی برای گرفتن اسم از cin استفاده می کنی دیگه فاصله نمی تونی استفاده کنی می تونی به جاش از getline استفاده کنی