PDA

View Full Version : سوال: split string



meysamg_alone
یک شنبه 27 اردیبهشت 1388, 15:27 عصر
سلام به همه
یه سوال , ما یه متغیر دارم که توش رشته هست مثلا این رشته

test1*test2*test3*test4*test5*test6
خوب حالا من می خوام که ستاره ها حذف بشن و کلمه هاییی تویه یه ارایه رشته ای ذخیره بشن
یعنی یه ارایه رشته ای داشته باشیم که index صفرش بشه test1 و index2 بشه test2 وتا اخرش همین جوری بشه یعنی در حقیقت اون ستاره ها فقط جنبه یه نشانه رو دارن برایه این که اون نوشته ها از هم جدا بشن که ما بتونیم تشخص بدیم تویه vb این کارو با دستور split انجام می دنن به این شکل

dim a() as string
a = split (str1,"*")
:متفکر:

حسین محمدی
یک شنبه 27 اردیبهشت 1388, 16:27 عصر
با سلام

البته سوال شما باید در قسمت برنامه نویسی با زبان C و ++C (http://barnamenevis.org/forum/forumdisplay.php?f=45) مطرح می شد.



char str[] = "test1*test2*test3*test4*test5*test6";
char seps[] = "*";
char *token;

char strArr[10][16];

token = strtok(str, seps);
int i = 0;

while (token)
{
strcpy(strArr[i], token);
token = strtok(NULL, seps);
i++;
}

tdkhakpur
یک شنبه 27 اردیبهشت 1388, 16:58 عصر
سلام :
این کد رو تست کن
موفق باشید.


char str[] = "test1*test2*test3*test4*test5*test6";
char strArr[10][16];
int c=0, cstr=0;
for( int i=0; i<strlen(str); i++){
if( str[i]=='*'){
strArr[cstr++][c] = 0;
c = 0;
}
else
strArr[cstr][c++] = str[i];
}

meysamg_alone
یک شنبه 27 اردیبهشت 1388, 17:05 عصر
ممنون از جواب .
فقط یه سوال دیگه

char strArr[10][16];

تویه این کد شما ارایه رو دو بعدی تعریف کردین میشه این کدو توضیع بدین من یه تازه کارم
بعد مشه این کدی رو که نوشتین به شکلی بنویسین که ارایه تهی تعریف بشه یعنی هیچ حد و مرزی نداشته باشه و با توجه به رشته ورودی ارایه گسترش پیدا کنه مثلا اون رشته که ورودی ماست معلوم نیست چنتا عضو داره ؟
بعد مثلا اگه یه ارایه تعریف کردیم که تعداد عضو هاش مشحص نبود بعدا تویه یه تابع به یه تعدادی گسترش پیدا کرد بعد می خوام بدونم که مثلا چه جوری ما می تونیم بفهمیم که این ارایه چنتا عضو داره یعنی تابعی هست که ارایه ورودی داشته باشه و خروجیشم تعداد عضو های ارایه باشه ؟!

meysamg_alone
یک شنبه 27 اردیبهشت 1388, 17:20 عصر
token = strtok(str, seps);

این کدو یه توضیعی می دین که چه کار می کنه ؟

meysamg_alone
یک شنبه 27 اردیبهشت 1388, 17:38 عصر
token = strtok(NULL, seps);

این کدم هم اصلا نمیتونم بفهمم که چه کار میکنه

tdkhakpur
یک شنبه 27 اردیبهشت 1388, 17:42 عصر
سلام:


این کدو یه توضیعی می دین که چه کار می کنه ؟

دوستمون برنامه خیلی واضحی رو ارائه دادن.

token = strtok(str, seps);
در بالا این کد جواب میده ولی از نظر من اشکالاتی رو در کارهای بزرگتر به بار میاره مثلا نخواییم به str تغییراتی تحمیل بشه و یا عوامل پشته ها.
ولی مفهومش اینه که با توجه به اینکه seps همون * هست strtokباعث میشه رشته str بررسی بشه و فقط کلمه ای که قبل از علامت ستاره داره بصورت رشته برگردونده بشه.
ولی در مور سوالهای دیگه باید عرض کنم که باید از لینک لیستها استفاده کنی.
موفق باشید.

حسین محمدی
یک شنبه 27 اردیبهشت 1388, 18:18 عصر
با سلام

در جایی که شما تعداد عناصر آرایه را نمی دانید از پوینتر استفاده کنید.

مثلا به جای اینکه شما از یک آرایه دو بعدی استفاده کنید از یک آرایه یک بعدی از جنس پوینتر استفاده کنید:

مثلا در مثال قبل:



char *strArr[10];


اگر به این شکل تعریف کنید به این معناست که شما 10 عنصر رشته ای دارید ولی طول هر عنصر را نمی دانید.

ولی دقت داشته باشید که قبل از مقدار دهی به هر عنصر برای آن فضای لازم را تخصیص دهید:



while (token)
{
strArr[i] = new char[strlen(token) + 1];
strcpy(strArr[i], token);


در ضمن در اینجا هنوز شما 10 عنصر دارید که طول هر کدام نا مشخص است.

ولی اگر تعداد عناصر را نمی دانید ولی طول را می دانید و هر کدام 16 است به این شکل بنویسید.



typedef char Str16[16];
Str16 *strArr;

token = strtok(str, seps);
int i = 0;

strArr = new Str16[10];

while (token)
{
strcpy(strArr[i], token);
token = strtok(NULL, seps);
i++;
}


ضمنا فراموش نکنید فضاهایی را که توسط new گرفته اید با دستور [] delete به سیستم عامل بازگردانید.

حسین محمدی
یک شنبه 27 اردیبهشت 1388, 18:29 عصر
دستور strtok در واقع از ابتدای پارامتر اول (یعنی str) تا پیدا کردن یکی از کاراکتر های seps را به ما بر می گرداند.

البته برای چنین مواردی شما می توانید از کلاسهای CString و CStringArray استفاده کنید و از متدهای این کلاسها استفاده کنید.

meysamg_alone
یک شنبه 27 اردیبهشت 1388, 19:42 عصر
ممنون از جواب کاملتون فقط یه 2 تا سوال دیگه
1- کلاس CString از کجا میاد من win32 کار می کنم فکر نکنم چنین کالی داشته باشه ؟!
2- اگه هم طول کارکتر ها و هم تعداد ارایه مجهول باشه میشه چه کار باید کرد یعنی باید همیشه یه پیش فرض در نظر بگیریم که مثلا 255 تا طول کارکتر های هر ارایه حالا اگه 1 کارتر شد چی !
نمیشه جوری تعریف کرد که هم این طول ارایه مجهول باشه هم تعداد ارایه ؟!؟!

Nima_NF
یک شنبه 27 اردیبهشت 1388, 20:42 عصر
1- کلاس CString از کجا میاد من win32 کار می کنم فکر نکنم چنین کالی داشته باشه ؟!
CString در MFC هست.
در win32 شما می توانید از کلاس string (یا wstring و یا basic_string) استفاده کنید که جز استاندارد ++C هست و کارها را ساده می کند.. string چیزی شبیه CString هست و یک سری متد دارد.



2- اگه هم طول کارکتر ها و هم تعداد ارایه مجهول باشه میشه چه کار باید کرد یعنی باید همیشه یه پیش فرض در نظر بگیریم که مثلا 255 تا طول کارکتر های هر ارایه حالا اگه 1 کارتر شد چی !
نمیشه جوری تعریف کرد که هم این طول ارایه مجهول باشه هم تعداد ارایه ؟!؟!
تعداد کارکترها را از ستاره قبلی تا ستاره بعدی می شمارید، سپس با استفاده از اشاره گر به char یا TCHAR و با تخصیص حافظه new به همان مقدار حافظه تخصیص می دهید.

meysamg_alone
یک شنبه 27 اردیبهشت 1388, 21:21 عصر
typedefchar Str16[16];
Str16 *strArr;

token = strtok(str, seps);
int i = 0;

strArr = new Str16[10];

while (token)
{
strcpy(strArr[i], token);
token = strtok(NULL, seps);
i++;
}

بابت جواب اولتون ممنون ولی در مورد شماره 2 منظور من اینه که هم تعداد ارایه نامعلوم باشه هم تعداد کلمه ها
الان تویه مثال بالا تعداد کلمه ها رو 16 تا در نظر گرفته حالا اگه تعداد کلمه ها از 16 تا بیشتر شد یا کمتر شد چه جوری باد اونو عوض کنیم منظور من اینه !؟

Nima_NF
دوشنبه 28 اردیبهشت 1388, 00:23 صبح
برای این جور مواقع بهتر هست از لیست پیوندی استفاده کنید (کلاس list یا vector در ++C). در این کلاس شما به راحتی می توانید در هر مرحله از حلقه شما اگر رشته ای وجود داشت آن را به انتهای لیست پیوندی اضافه کنید (insert یا push_back ). به این شکل از صفر عضو شروع می کنید و کم کم یک عضو جدید اضافه می کنید. ضمن اینکه خودتان با استفاده از متد resize و reverse می توانید حافظه را کنترل کنید (و یا تخصیص دهید) تا کارآیی افزایش یابد.

داخل این لیست می تواند همان رشته هایی باشد که با new ساخته اید یا مجددا یک لیست پیوندی دیگر باشد.



#include <list>

list <char*> myList;

meysamg_alone
دوشنبه 28 اردیبهشت 1388, 11:54 صبح
درسته اقا نیما این دقیقا همون چیزی هست که من می خواستم فقط یه مشکلی هست !
شما همه چیزو در باره ذخیره کردن گفتین بازیابی چی چه جوری میشه چیزی رو که توش ذخیره کردیم رو دوباره ازش بگیریم !؟
من یه تازه کارم هنوز راه نیوفتادم

Nima_NF
دوشنبه 28 اردیبهشت 1388, 17:10 عصر
در list دسترسی رندوم راحت نیست و باید با iterator تک تک بشمارید و به جلو بروید:




list <char*> myList;
list <int>::iterator Iter;

// fill it

for ( Iter = myList.begin( ); Iter != myList.end( ); Iter++ )
{
// use them

cout << *Iter;

}

اگر قرار هست همانند آرایه ها عمل کنید و با شماره ایندکس به خانه ها دسترسی داشته باشید به جای list از vector استفاده کنید. برای دسترسی عملگر [] تعریف شده است و می توانید همانند آرایه برا گرفتن عمل کنید:



vector <char*> strVec;
char* tempStr1;

string s1 ( "hello 1" );
tempStr1 = new char[s1.length()+1];
strcpy( tempStr1, s1.c_str() );
strVec.push_back( tempStr1 );

// add more, do the same

cout << strVec[0] ; // print hello 1
// cout << strVec[1] << endl ;

در مثال فوق از کلاس string استفاده کردم، رشته را با همان طول اضافه کردم، سپس با متد length به علاوه یک واحد برای \0 حافظه تخصیص دادم. حال می توان رشته را با push_back به vector اضافه کرد. و مانند آرایه ای از رشته ها خواند.

ضمنا می توانید به شکل زیر هم با متد insert رشته مورد نظر خود را داخل string کپی کنید:



vector <char*> strVec;
char* tempStr1;

string s1;
char *myStr = "hello 2";
s1.insert (0, myStr );

tempStr1 = new char[s1.length()+1];
strcpy( tempStr1, s1.c_str() );
strVec.push_back( tempStr1 );

cout << strVec[0] ;


فراموش نکنید که تک تک محتویات لیست را با delete پاک کنید تا حافظه گرفته شود(همانی که با new تخصیص دادید) و سپس متد clear یل erase را فراخوانی کنید.

meysamg_alone
دوشنبه 28 اردیبهشت 1388, 20:22 عصر
ممنون اقا نیما فقط یادتون رفت بگین که

#include<vector>
من خودم حدس زدم
به هر حال با وجود شما و دوستان دیگه من احساس خوبی دارم برایه یاد گیری این زبون

meysamg_alone
دوشنبه 28 اردیبهشت 1388, 22:32 عصر
فقط یه سوال دیگه !
ببخشید من چه جوری باید بفمم که این رایه چندتا عضو داره مثلا من 5 بار به این ارایه عنصر اظافه کردم خوب حالا چه جوری باید بفهمم که این ارایه 5 عضو داره بدونه این که خدم مقعی که دارم بهش عنصر اظافه می کنم یا کم کنم اونو بشمارم یعنی خود این کلاس متغیری یا تابعی نداره که از رویه اون بشه فهمید که ارایه ما چند عضو داره ؟

Nima_NF
سه شنبه 29 اردیبهشت 1388, 00:16 صبح
به چند نکته توجه کنید:

1- حتما MSDN را تهیه کنید. (تاکید اکید!)

2- وقتی کلاسی معرفی می شود، حتما متدهایی دارد. در MSDN نام آن کلاس را وارد کنید (مثلا vector class) سپس در پایین همان صفحه که برای معرفی آن کلاس هست، بخشی تحت عنوان مثلا vector members هست، با کلیک بر روی آن لیست توابع/متدها ، تعریف مجدد عملگرها نشان داده می شود. مثال هم به قدر کافی برای هر متد وجود دارد.(دقت کنید که ممکن هست کلاسی از کلاس های دیگر ارث برده باشد و آن ها هم متدهایی داشته باشند که قابل استفاده است)


این کلاس متغیری یا تابعی نداره که از رویه اون بشه فهمید که ارایه ما چند عضو داره ؟ تابع size عضو این کلاس هست که تعداد عناصر vector/list را می دهد.

meysamg_alone
سه شنبه 29 اردیبهشت 1388, 09:45 صبح
باشه حتما ممنون:لبخندساده:

sadeghg
دوشنبه 22 تیر 1388, 13:06 عصر
سلام
چه تور میشه توابع vector مثل push_back یا insert رو تعریف کرد تا هر وقت برنامه اجرا شد با استفاده از توابع تعریف شده ما برنامه عمل کنه ؟
یه چیزی شبیه سربار گذاری عملگر ها

Nima_NF
سه شنبه 23 تیر 1388, 10:10 صبح
سلام
چه تور میشه توابع vector مثل push_back یا insert رو تعریف کرد تا هر وقت برنامه اجرا شد با استفاده از توابع تعریف شده ما برنامه عمل کنه ؟
یه چیزی شبیه سربار گذاری عملگر ها

این سوال باید در یک تاپیک جداگانه پرسیده می شد چون ربطی به این تاپیک کنونی ندارد.

توابع ذکر شده شما عضو معمولی کلاس هستند و از نوع virtual نیستند پس نمی توانید از کلاس vector به ارث ببرید و نمی توانید آن ها را مجددا تعریف کنید. مگر اینکه به سورس کدها دسترسی داشته باشید و با افزودن virtual به این تابع آن را تغییر دهید. به هر حال به خاطر اینکه از جزییات کامل پیاده سازی vector در همان کلاس اطلاع ندارید بسیار مشکل هست و تقریبا غیر ممکن.

پیشنهاد می کنم ار کلاس vector کلاسی دیگر به ارث ببرید و دو تابع با نامی نزدیک به آن توابع تعریف کنید، این طوری هم توابع قبلی را دارید و هم توابع جدید را. (البته اگر کلاس های استاندارد C++ اجازه ارث بردن را بدهند)

sang9111
سه شنبه 23 تیر 1388, 14:36 عصر
من چند وقت پیش یه کار دانشجویی برای یه بنده خدا انجام ادم که مربوط به یه ماشین حساب مهندسی میشد که باید هر عبارت که به صورت جدا جدا تشخیص می داد حساب می کرد بعدبر اساس عملگر عمل انجام می داد
البته این کد ها ناقص هستند کاملشو الان ندارم و کلا اشکال ساختاری دارن debug نکردمش این کد ولی می تونه مفید باشه
من برای ذخیره هر عبارت از لیست پیوندی استفاده کردم و و یک حالت بازگشتی دادم
البته می گم اشکال داره ولی بد نیست

#include <iostream.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ctype.h>

#define nul " "
struct node
{
char jomle_g[40];// baraye zakhire jomle gereh ha
double adad; //zakhire adade marbut be har gereh
int shomar;//shomarande node
struct node *next;//barye eshare be gereh badi
};

char *tahlil(char []);
double mohaseb(char []);
double mohaseb2(char []);
void control(char []);
void list(char []);
double list(double ad);
char jomle[150];
int main()
{

cout<<"jomle ra vared kon"<<"\n";
cin>>jomle;
control(jomle);
list(jomle);
return 0;
}
//*************************
void control(char jom[150])
{
int p_baz=0,p_baste=0;
int i=0,hg;
hg=strlen(jom);
while(i<hg)//****braye controll paranteaz ha
{
if(jom[i]=='(')
p_baz++;
else if(jom[i]==')')
p_baste++;
if(p_baz != p_baste)
{cout<<"tedad parantez ha moshkel darad"<<"\n"; return;}
if(jom[i]=='(' && isdigit(jom[i+1])!=0 && jom[i+2]==')')
{cout<<"jomle dochar moshkel ast"<<"\n"; return;}
}
}
//***************************
char *tahlil(char jom[40])
{
int pbaz=0,pbaste=0;
bool www = true,ww2=true;
char alamat[20];
char ebarat[40];
int i=0,j=0,n=0;
int a=0;
a = strlen(jom);
while(i<a)
{
if(jom[i] =='(') pbaz++;
if(jom[i] ==')') pbaste++;

if(www == true) {
if(jom[i]=='(' && jom[i+1]=='(')
{ www=false; i++; continue;} }//end if
if(ww2 == true) {
if(jom[i]==')' && jom[i+1]==')')
{ ww2=false; i++; continue;}
if(jom[i]==')' && jom[i+1]==')')
{ ww2=false; i++; continue;}
}//end if

if(pbaz == pbaste)//baraye bariye alamt
{
if(jom[i]=='+' && jom[i+1]=='(')
{alamat[j]='+'; j++; return *ebarat; strcpy(ebarat,nul); i++; www = true; n=0;ww2=true;
continue;}

if(jom[i]=='-' && jom[i+1]=='(')
{alamat[j]='-'; j++; return *ebarat; strcpy(ebarat,nul); i++; www = true; n=0;ww2=true;
continue;}

if(jom[i]=='*' && jom[i+1]=='(')
{alamat[j]='*'; j++; return *ebarat; strcpy(ebarat,nul); i++; www = true; n=0;ww2=true;
continue;}

if(jom[i]=='/' && jom[i+1]=='(')
{alamat[j]='/'; j++; return *ebarat; strcpy(ebarat,nul); i++; www = true; n=0;ww2=true;
continue;}

if(jom[i]=='^' && jom[i+1]=='(')
{alamat[j]='^'; j++; return *ebarat; strcpy(ebarat,nul); i++; www = true; n=0;ww2=true;
continue;}

if(jom[i]=='+' && isalnum(jom[i-1]) !=0 && isalnum(jom[i+1]) !=0)
{alamat[j]='+'; j++; return *ebarat; strcpy(ebarat,nul); i++; www = true; n=0;ww2=true;
continue;}

if(jom[i]=='-' && isalnum(jom[i-1]) !=0 && isalnum(jom[i+1]) !=0)
{alamat[j]='-'; j++; return *ebarat; strcpy(ebarat,nul); i++; www = true; n=0;ww2=true;
continue;}

if(jom[i]=='*' && isalnum(jom[i-1]) !=0 && isalnum(jom[i+1]) !=0)
{alamat[j]='*'; j++; return *ebarat; strcpy(ebarat,nul); i++; www = true; n=0;ww2=true;
continue;}

if(jom[i]=='/' && isalnum(jom[i-1]) !=0 && isalnum(jom[i+1]) !=0)
{alamat[j]='/'; j++; return *ebarat; strcpy(ebarat,nul); i++; www = true; n=0;ww2=true;
continue;}

if(jom[i]=='^' && isalnum(jom[i-1]) !=0 && isalnum(jom[i+1]) !=0)
{alamat[j]='^'; j++; return *ebarat; strcpy(ebarat,nul); i++; www = true; n=0;ww2=true;
continue;}//end if

if(jom[i]=='+' && jom[i-1]==')')
{alamat[j]='+'; j++; return *ebarat; strcpy(ebarat,nul); i++; www = true; n=0;ww2=true;
continue;}

if(jom[i]=='-' && jom[i-1]==')')
{alamat[j]='-'; j++; return *ebarat; strcpy(ebarat,nul); i++; www = true; n=0;ww2=true;
continue;}

if(jom[i]=='*' && jom[i-1]==')')
{alamat[j]='*'; j++; return *ebarat; strcpy(ebarat,nul); i++; www = true; n=0;ww2=true;
continue;}

if(jom[i]=='/' && jom[i-1]==')')
{alamat[j]='/'; j++; return *ebarat; strcpy(ebarat,nul); i++; www = true; n=0;ww2=true;
continue;}

if(jom[i]=='+' && jom[i-1]==')')
{alamat[j]='+'; j++; return *ebarat; strcpy(ebarat,nul); i++; www = true; n=0;ww2=true;
continue;}

if(jom[i]=='^' && jom[i-1]==')')
{alamat[j]='^'; j++; return *ebarat; strcpy(ebarat,nul); i++; www = true; n=0;ww2=true;
continue;}
}//end if
ebarat[n] = jom[i];
www = false;
}// end while

}
//********************************
double mohaseb (char jom[30])
{
double adad;
int i=0;

switch(jom[i])
{
case's':
adad = sin(mohaseb2(jom));//sin(x)
break;
case'c':
adad = cos(mohaseb2(jom));//cos(x)
break;
case't':
adad = tan(mohaseb2(jom));//tan(x)
break;
case'l':
adad = log10(mohaseb2(jom));//log(x)
break;
default:
adad = mohaseb2(jom);//agar faghat adad bashad
}//end switch
return adad;
}//payane tabe
//***********************************************
double mohaseb2(char jom[30])
{
double adad;//baraye zakhire reshte be adad
int i=0;
char ad[10]; // zakhire adad dar ebarat
while(jom[i]==')' || jom[i]==' ')
switch(jom[i])
{
case'1':
ad[i]='1';
break;
case'2':
ad[i]='2';
break;
case'3':
ad[i]='3';
break;
case'4':
ad[i]='4';
break;
case'5':
ad[i]='5';
break;
case'6':
ad[i]='6';
break;
case'7':
ad[i]='7';
break;
case'8':
ad[i]='8';
break;
case'9':
ad[i]='9';
break;
case'0':
ad[i]='0';
break;
case'-':
ad[i]='-';
break;
case'.':
ad[i]='.';
break;
}//end switch
adad = atof(ad);//tabdil reshte be adad
return adad;
}
//************************************************** **
void list(char jom[40])
{
char hhh[45];
strcpy(hhh,tahlil(jom));
struct node *first,*end,*point;//sakhtar baraye ejad list peyvandi******first____end____point
point = (struct node *)malloc(sizeof(struct node));
strcpy(point->jomle_g,hhh);

first = NULL;
point->next=NULL;
if(first==NULL)
first=end=point;
else
{
end->next=point;
end=point;
}
struct node *current;
current = (struct node *)malloc(sizeof(struct node));
current = first;


while(current!=NULL)
{
int f,d=0;
f=strlen(current->jomle_g);
while(d<f) {
if(current->jomle_g[d] == '(' && current->jomle_g[d+1] == '(' || current->jomle_g[d] == '(' && current->jomle_g[d-1] == '(' )
{list(current->jomle_g);}
current->adad = mohaseb(current->jomle_g);
list_2(current->adad);
}
}
}
//************************************
double list(double ad)
{
char alam[20];
int jam=0,taf=0,tagh=0,zarb=0,tavan=0;//baraye tashkhis tedad har amalgar
struct node *f_2,*e_2,*p_2;
p_2 = (struct node *)malloc(sizeof(struct node));
p_2->shomar++;
int q=0;
while(q<strlen(alam))
{
if(alam[q] == '/') tagh++;
if(alam[q] == '*') zarb++;
if(alam[q] == '-') taf++;
if(alam[q] == '+') jam++;
if(alam[q] == '^') tavan++;
}
p_2->adad = ad;
f_2 = NULL;
p_2->next=NULL;
if(f_2==NULL)
f_2=e_2=p_2;
else
{
e_2->next=p_2;
e_2=p_2;
}
struct node *current;
current = (struct node *)malloc(sizeof(struct node));
while(current!=NULL)
{if(alamat[i] == '/')
{tagh--; while(current->shomar == i){list_2(current->adad / next->adad)}}
if(alamat[i] == '*')
{zarb--; while(current->shomar == i){list_2(current->adad * next->adad)}}
if(alamat[i] == '-')
{taf--; while(current->shomar == i){list_2(current->adad - next->adad)}}
if(alamat[i] == '+')
{jam--; while(current->shomar == i){list_2(current->adad + next->adad)}}
if(alamat[i] == '^')
{tavan--; while(current->shomar == i){list_2(pow(current->adad,next->adad))}}
}//end while
return *f;
}