انجمن‌های فارسی اوبونتو

لطفاً به انجمن‌ها وارد شده و یا جهت ورود ثبت‌نام نمائید

لطفاً جهت ورود نام کاربری و رمز عبورتان را وارد نمائید


توزیع گنو/لینوکس اوبونتو ۲۰ ساله شد 🎉

نویسنده موضوع: در مورد کتابخانه ncurses چه میدانید؟  (دفعات بازدید: 6194 بار)

0 کاربر و 3 مهمان درحال مشاهده موضوع.

آفلاین بهنام م ک

  • Full Member
  • *
  • ارسال: 215
  • جنسیت : پسر
در مورد کتابخانه ncurses چه میدانید؟
« : 13 مهر 1392، 09:26 ب‌ظ »
دوستان در مورد توابع موجود در این کتابخانه و طرز استفاده شون چه چیزایی بلدین؟
تا حالا با کدوما کار کردین و چه مشکلاتی باهاشون داشتین؟
بهرحال این کتابخانه بیش از هر کتابخانه ای برای نوشتن برنامه ها و پروژه های دانشجویی لازمه و هر روزه ده ها سرچ در مورد این کتابخانه(در دانشکده ی ما) صورت میگیره و بدبختانه منابع فارسی چندانی وجود نداره.بهتره از جایی این کار شروع بشه.
بسم الله
« آخرین ویرایش: 15 مهر 1392، 10:07 ب‌ظ توسط کیسه ل »
من از آنچه تو میگویی بیزارم ولی تا پای مرگ از حق تو برای گفتن آن دفاع میکنم

آفلاین vandu

  • Hero Member
  • *
  • ارسال: 741
  • جنسیت : پسر
پاسخ : در مورد کتابخانه ncurses.h چه میدانید؟
« پاسخ #1 : 13 مهر 1392، 11:23 ب‌ظ »
فکر میکنم این کتابخانه برای رسم گرافیک در text-mode هست و الان دیگه زیاد کاربردی نیست.

این رو ببینید:
http://www.c-for-dummies.com/ncurses
Nothing is particularly hard if you divide it into small jobs

Henry Ford

آفلاین بهنام م ک

  • Full Member
  • *
  • ارسال: 215
  • جنسیت : پسر
پاسخ : در مورد کتابخانه ncurses.h چه میدانید؟
« پاسخ #2 : 14 مهر 1392، 09:46 ب‌ظ »
http://invisible-island.net/ncurses/ncurses-intro.html
برای استفاده از این کتابخانه لازمه که کتابخانه ی ncurses رو نصب کنین چون به طور پیشفرض تو اوبونتو(و خیلی از توزیعا)نصب نیست.
برای نصبش این کارو بکنین:
sudo apt-get install ncurses-dev
با این کار سریعا کتابخانه ی مورد نظر و چندتا dependency دیگه نصب میشه و با خیال راحت و بدون ریستارت میتونین کارتونو شروع کنین.
« آخرین ویرایش: 22 مهر 1392، 02:43 ب‌ظ توسط کیسه ل »
من از آنچه تو میگویی بیزارم ولی تا پای مرگ از حق تو برای گفتن آن دفاع میکنم

آفلاین mojtabarezaei76

  • Full Member
  • *
  • ارسال: 179
  • جنسیت : پسر
پاسخ : در مورد کتابخانه ncurses.h چه میدانید؟
« پاسخ #3 : 15 مهر 1392، 06:02 ب‌ظ »
فکر کنم جایگزین conio.h باشه(البته من زیاد سی بلدنیستم)
دنیا را دو گونه می توان تغییر داد: با قلم (كاربست اندیشه) و با شمشیر (كاربست زور)

آفلاین nixoeen

  • ناظر انجمن
  • *
  • ارسال: 4872
  • جنسیت : پسر
  • masoft قدیم
پاسخ : در مورد کتابخانه ncurses.h چه میدانید؟
« پاسخ #4 : 15 مهر 1392، 06:27 ب‌ظ »
چند تا اصلاحیه :)
گفتن کتابخانه ncurses.h اشتباهه. کتابخانه ncurses درسته. ncurses.h تنها یک Header هستش، نه یک کتابخانه.

نمی‌شه گفت ncurses جایگزین conio هستش. ولی خوب کسی که بخواد برنامه‌ای برای محیط متنی با رابط کاربری مناسب بنویسه، بهترین گزینه هستش.

آفلاین بهنام م ک

  • Full Member
  • *
  • ارسال: 215
  • جنسیت : پسر
پاسخ : در مورد کتابخانه ncurses چه میدانید؟
« پاسخ #5 : 22 مهر 1392، 10:30 ق‌ظ »
نوشتن hello world معروف با استفاده از ncurses :
#include <ncurses.h>

int main()
{
initscr();
refresh();
printw("Hello world!!!!\n");
refresh();
getch();
endwin();
return 0;
}
خب الان کدای بالا رو تو یه ادیتور بنویسید و با پسوتد  c. ذخیره کنید(البته پسوند اصلا مهم نیست)
مثلا من اسمشو hello.c گذاشتم و حتما باید اینجوری کامپایلش کنم:
gcc -o hello hello.c -lncursesتو قسمت کامپایل تنها چیزی که مهمه lncurses- هست که به gcc میگه که باید بره یه جای دیگه دنبال کتابخانه ی ncurses بگرده و از مسیر مسیر پیشفرض نمیتونه پیداش کنه.
حالا نوبت اجرا رسیده:
./hello

اما هرکدوم از توابع بالا چه کاری انجام میدن؟
()initscr
این تابع یه بافر مخصوص برای ncurses میسازه و اونو در اختیار ما قرار میده تا برای کارامون به جای صفحه ی ترمینال ازش استفاده کنیم.یعنی درواقع برای ما یه صفحه ای مجازی شبیه ترمینال میسازه و مدیریت کامل اونو در اختیار ما قرار میده تا هرکاری که بخواییم با اون انجام بدیم و بعدا محتویات اونو روی ترمینال نمایش بدیم و نتیجه جوری باشه که انگار با خوده ترمینال کار کردیم.
این بافر روی رم سیستم تعبیه میشه و مث صفحه ای عمل میکنه که ما اونو نمیبینیم اما میتونیم داخلش بنویسیم و حتی کرسر رو به راحتی جابجا کنیم(کاری که بدون این صفحه ی مجازی و ncurses نمیتونیم انجام بدیم).
کسایی که تو ویندوز با c کار کرده باشن حتما کتابخانه ی conio رو میشناسن.اونجا توابعی مث ()getch() , gotoxy و ()clrscr رو دیدن و از کار کردن باهاشون لذت بردن اما متاسفانه این کتابخانه و توابع در standard C وجود ندارن و در واقع اون کتابخانه ی conio محصول بورلتده که برای کاربرا نوشته و در لینوکس چنین چیزی نداریم.

()refresh
این توابع وظیفه ی نوشتن بافر را بر روی ترمینال به عهده دارد.اما چون اینجا فعلا ما چیزی داخل بافر ننویشیم پس نقش ()clrscr رو تو ویندوز ایفا میکنه.اما بعدا برای مقاصد مهم تری هم ازش استفاده میکنیم.
اینجا اگه این خط رو هم ننویسید مشکلی پیش نمیاد اما همیشه قشنگتر اینه که همون اول کار بافر رو بیارید بریزید تو ترمینال تا کارتون استاندارد باشه.

()printw
این تابع بر روی window مجازی ما مینویسه!
پس هر رشته ای که ما بهش بدیم رو میره تو بافر و بر روی پنجره ی مجازی مینویسه.اینجا دقت کنین که ما هنوز چیزی رو تو ترمینال ننویشتیم بلکه رشته ی ما داخل بافر که مستقل از پنجره ی ترمیناله قرار گرفته.

()refresh
حالا وقت اینه که بافر رو بیاریم بریزیم تو پنجره ی ترمینال!
پس با این کار ما رشته مون رو روی صفحه ی ترمینال چاپ میکنیم!

()getch
دیگه فک کنم همه این تابعو میشناسن مخصوصا ویندوز کارا!
این تابع منتظر گرفتن کلیدی از کاربر میشه و درواقع اجرای برنامه رو بلاک میکنه تا خط بعدی اجرا نشه.یعنی تا کابر یه کلید رو از صفحه کلید فشار نده برنامه همونجا میمونه و تکون نمیخوره

()endwin
خب الان دیگه کارمون با اون بافر و پنجره ی مجاز تموم شد چون هرچی لازم بود رو تو پنجره ی ترمینال نویشتیم و الان وقتشه که اون بافر رو از داخل رم سیستم پاک کنیم چون اگه همونجوری بمونه دردسر ساز میشه پس با این تابع گردنشو میزنیم و از رم میندازیمش بیرون.

خسته نباشید ;)
« آخرین ویرایش: 22 مهر 1392، 10:33 ق‌ظ توسط کیسه ل »
من از آنچه تو میگویی بیزارم ولی تا پای مرگ از حق تو برای گفتن آن دفاع میکنم

آفلاین بهنام م ک

  • Full Member
  • *
  • ارسال: 215
  • جنسیت : پسر
پاسخ : در مورد کتابخانه ncurses چه میدانید؟
« پاسخ #6 : 23 مهر 1392، 09:41 ق‌ظ »
حرکت کاراکتر بر روی صفحه ی نمایش:
خب الان یه برنامه مینویسیم که یه نوشته ای داخل ترمینال حرکت کنه.
این نوشته با فشار کلید p از صفحه کلید متوقف میشود و کلید r کاراکتر را دوباره به حرکت در می آورد.
کلید q هم برای خروج از برنامه استفاده میشه.

#include <ncurses.h>
#include <unistd.h>


int main()
{
  initscr();
  refresh();
  noecho();
 
  char command;
  int i=15 , j=1;
 
  while(1)
  {
    clear();
    move(j , i);
    printw("_UBUNTU");
    refresh();
    usleep(150000);
    i++;
    if(i>60)
    {
      j++;
      i = 15;
    }
    nodelay(stdscr,1);
    command = (char)getch();
    if(command == 'q')
      break;
    else
      if( command == 'p')
      {
move(7,34);
printw("Pausing . . . \n");

printw("\n\nPress r to Resume or q to quite:");
while(1)
{
  command = (char)getch();
  if(command == 'q')
  {
    clear();
    move(9,34);
    printw("Quiting . . . ");
    refresh();
    usleep(1070000);
    endwin();
    return 0;
  }
  if(command == 'r')
    break;
}
      }
    }
    clear();
    move(9,34);
    printw("Quiting . . . ");
    refresh();
    usleep(1070000);
    endwin();
    return 0;
}

الان اینجوری کامپایل و اجراش کنین:
gcc ubuntu ubuntu.c -lncurses

./ubuntu

و اما معرفی توابع جدید:
()noecho
همونجور که از اسم تابع معلومه وظیفه ی مخفی کردن کاراکترهایی که کاربر برای توقف و یا ادامه و خروج برنامه تایپ میکند را بر عهده دارد.یعنی با این کار دیگر هیچ  کدام از ورودی های کاربر که از طریق صفحه کلید وارد میشه بر روی صفحه نمایش داده نمیشه
این تابع یکی از توابه ncurses هست

()clear
 این تابع همزاد لینوکسی ()clrscr در بورلنده و ویندوزه که انصافا هم چیز خوب و قشنگیه
این تابعم باز مال ncurses عه

(move(i,j
اینم همزاد تابع ()gotoxy در ویندوزه که کرسر رو به مکان خاصی با مختصات i , j در صفحه میبره.
فقط توجه کنید که i مختصات ارتفاع و j مختصات ظول صفحه ست!
بدیهیه که این تابعم داخل ncurses قرار داره

()nodelay
همونطور که در قسمت قبل گفتم تابع ()getch باعث بلاک شدن برنامه میشه یعنی تا زمانی که که کاربر کاراکتری رو وارد نکنه اجرای برنامه به خط بعدی نمیره.
اما در نقشه ی برنامه ی ما همچین چیزی نباید اتفاق بیوفته.باید برنامه اجرا شود و هرگاه که کاربر کلیدی را فشار داد آنگاه کلید دریافت شده و تصمیم اتخاذ شود.
برای اینکه تابع ()getch برنامه را بلاک نکند از این تابع داخل ncurses استفاده میکنیم.
این تابع دو ورودی میگیرد که یکی صفحه ی مجازی کنونیه که داریم باهاش کار میکنیم و دیگری یه مقداره بولینه که اگه 1 باشه به معنی اینه که تابع بیاد و از بلاک شدن برنامه جلوگیری کنه

()usleep
برای کنترل سرعت حرکت متن از این تابع استفاده میکنیم.
این تابع که درون کتابخانه ی unistd قرار دارد کل برنامه را به مدت فلان میلی ثانیه متوقف میکند
پس ورودی تابع برحسب میلی ثانیه ست!
« آخرین ویرایش: 23 مهر 1392، 10:09 ق‌ظ توسط کیسه ل »
من از آنچه تو میگویی بیزارم ولی تا پای مرگ از حق تو برای گفتن آن دفاع میکنم

آفلاین POo

  • Full Member
  • *
  • ارسال: 180
  • جنسیت : پسر
  • 12.04, debian testing
پاسخ : در مورد کتابخانه ncurses چه میدانید؟
« پاسخ #7 : 23 مهر 1392، 11:10 ق‌ظ »
کیسه ل دستت درد نکنه =D>  :D
آقا این سایتی که میگم رو یک نگاه بندازین:
http://cb.vu/شبیه سازِ ترمینالِ، البته خیلی نصفه نیمست.  اونجا با تایپ help میتونین دستوراتشو ببینین، ولی من چند تا مورد مدنظرم هست. تایپ کنید clock, matrix و snake اینا screensaver و بازی تحت ترمینالن. من clock اِشو تفریحی میخوام بسازم :D
اینا رو هم با  ncurses پیاده کردن؟!
پدرم روضه رضوان به دو گندم بفروخت     ناخلف باشم اگر من به جوی نفروشم

آفلاین بهنام م ک

  • Full Member
  • *
  • ارسال: 215
  • جنسیت : پسر
پاسخ : در مورد کتابخانه ncurses چه میدانید؟
« پاسخ #8 : 23 مهر 1392، 11:34 ق‌ظ »
اینا رو هم با  ncurses پیاده کردن؟!
والا نمیدونم که دقیقا با ncurses بوده یانه چون هرکسی میتونه برای کارای خودش یه کتابخانه بنویسه و ازش استفاده کنه اما با ncurses خیلی راحت میشه اونا رو پیاده سازی کرد.فقط یکم خلاقیت میخواد.
واقعا اون ساعت و ... تمرینای خیلی خوبی واسه مهندسی معکوس میشن اگه بتونی پیاده سازیش کنی. :)
من از آنچه تو میگویی بیزارم ولی تا پای مرگ از حق تو برای گفتن آن دفاع میکنم

آفلاین بهنام م ک

  • Full Member
  • *
  • ارسال: 215
  • جنسیت : پسر
پاسخ : در مورد کتابخانه ncurses چه میدانید؟
« پاسخ #9 : 23 مهر 1392، 11:36 ق‌ظ »
اون matrix  رو میتونید اینجوری تو اوبونتو داشته باشید:
sudo apt-get install cmatrix
من از آنچه تو میگویی بیزارم ولی تا پای مرگ از حق تو برای گفتن آن دفاع میکنم

آفلاین بهنام م ک

  • Full Member
  • *
  • ارسال: 215
  • جنسیت : پسر
پاسخ : در مورد کتابخانه ncurses چه میدانید؟
« پاسخ #10 : 30 مهر 1392، 09:30 ق‌ظ »
خب الان نوبت میرسه به مقایسه!
تقریبا همه ی اون کارایی که با ncurses انجام میشه رو میتونیم با سختی چند صدبرابر با سایر کتابخانه های غیر تخصصی هم انجام بدیم.
برای مثال این برنامه که اینجا گذاشتم همون کاره حرکت کاراکتر در صفحه رو انجام میده اما چون بدون ncurses نوشتم مجبور بودم خیلی از توابع رو خودم پیاده سازی بکنم:
#include <stdio.h>
#include <stdlib.h>


int lasti=0,lastj=0;

void goback(int x,int y )
{
printf("\033[%dA",x);
printf("\033[%dD",y);
}

void gotoxy(int x,int y )
{
extern int lasti, lastj;

goback(lasti, lastj);
int i;

for(i=0;i<x;i++)
printf("\n");
for(i=0;i<y;i++)
printf(" ");
lasti=x;
lastj=y;
}

int main(int argc , char* argv[])
{
printf( "\e[2J\e[H" );
usleep(100900);
int i = 1;
int j = 20;
// gotoxy(0,0);
// printf("A");
usleep(100900);


int b = 200;

while(b)
{
gotoxy(i,j-6);
printf("     _");
usleep(100900);
gotoxy(i,j);
printf(" BEHNAM");
usleep(100900);
j++;
if(j==60)
{
gotoxy(i,j--);
printf("      ");
j++;
i++;
j = 20;
gotoxy(i,j);
printf(" BEHNAM");
j++;

}

b--;
}

printf("\n\n");
return 0;

}

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

آفلاین بهنام م ک

  • Full Member
  • *
  • ارسال: 215
  • جنسیت : پسر
پاسخ : در مورد کتابخانه ncurses چه میدانید؟
« پاسخ #11 : 30 مهر 1392، 01:56 ب‌ظ »
ترکیب pthread و ncurses در بازی خرگوش و لاکپشت Hare & Turtle:

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

// Behnam Mohammad Karimi

#include <pthread.h>
#include <ncurses.h>
#include <unistd.h>
#include <sys/types.h>

#include <stdlib.h>       //exit

#ifndef pthread_attr_default /* For native POSIX threads */
#define pthread_attr_default NULL
#endif

 
struct location {
 
  int hx;
  int hy;
  int tx;
  int ty;
  int finish;
 
};

struct location loc;
 
void *show(void *ptr)
{
  clear();
  move(loc.hy,loc.hx);
  printw("H");
     
  move(loc.ty,loc.tx);
  printw("T");
   
  move(9,19);
  printw("------------------------------------------");
  move(14,19);
  printw("------------------------------------------");
  move(10,19);
  printw("|");
  move(13,19);
  printw("|");
  move(11,19);
  printw("|");
  move(12,19);
  printw("|");
 
  move(10,60);
  printw("|");
  move(13,60);
  printw("|");
  move(11,60);
  printw("|");
  move(12,60);
  printw("|");
     
  refresh();
  if(loc.finish == 0)
    pthread_exit(0);
 
}

void *moveH(void *ptr)

  if(loc.hx == loc.tx )
    loc.hx += (rand()%4 + 1);
 
  pthread_exit(0);
}

void *moveT(void *ptr)
{
    loc.tx += 1;

    pthread_exit(0);
}

void *judge(void *ptr)
{
  if(loc.hx > 60 )
  {
    loc.finish = 0;
    clear();
    move(10,35);
    printw("Hare win!!!");
    refresh();
  }
 
  if(loc.tx > 60)
  {
    loc.finish = 0;
    clear();
    move(10,35);
    printw("Turtle win!!!");
    refresh();
  }
  pthread_exit(0);
 
}

int main()
{
  initscr();
 
   loc.hx = 20;
   loc.hy = 11;
   loc.tx = 20;
   loc.ty = 12;
   loc.finish = 1;
   
  char *message = "null";   
 
  clear();
  move(loc.ty,loc.tx);
  printw("T");
   
  move(loc.hy,loc.hx);
  printw("H");
 
  move(9,19);
  printw("------------------------------------------");
  move(14,19);
  printw("------------------------------------------");
  move(10,19);
  printw("|");
  move(13,19);
  printw("|");
  move(11,19);
  printw("|");
  move(12,19);
  printw("|");
 
  move(11,60);
  printw("|");
  move(12,60);
  printw("|");
  move(10,60);
  printw("|");
  move(13,60);
  printw("|");
   
  refresh();

  sleep(1);

  pthread_t thread1, thread2 , thread3 , thread4;

  while(loc.finish)
  {
    pthread_create( &thread1, pthread_attr_default,
  (void *) moveH, (void *) message);
    sleep(1);
   
    pthread_create( &thread2, pthread_attr_default,
  (void *) moveT, (void *) message);
//     sleep(1);
   
    pthread_create( &thread4, pthread_attr_default,
  (void *) show, (void *) message);
   
    pthread_create( &thread3, pthread_attr_default,
  (void *) judge, (void *) message);
    pthread_join(thread3, NULL);
 
   
  }
  sleep(2);
  getch();
  endwin();
  exit (0);

}
کامپایل:
gcc -o name prog.c -lncurses -pthreadاجرا :
./name


کی میتونه این برنامه رو بهتر کنه؟
« آخرین ویرایش: 30 مهر 1392، 02:16 ب‌ظ توسط کیسه ل »
من از آنچه تو میگویی بیزارم ولی تا پای مرگ از حق تو برای گفتن آن دفاع میکنم