سوال «ورودی چطوری در حالت Raw کار می کند» بهانه خوبی هست تا برنامهای بسازیم که کاراکتر خوانده شده توسط تابع ()read را نشان در صفحه نمایش یا Screen نشان دهد
ما هم کد ASCII کاراکتر را نشان خواهیم داد و هم اگر کارکتر قابل چاپ باشد (یعنی مثلا CTRL یا NULL یا DEL نباشد) آن را به صورت کاراکتر چاپ کنیم.
کد از این قرار هست:
این هم کد کامل:
#include <unistd.h> #include <termios.h> #include <stdlib.h> #include <stdio.h> #include <ctype.h> struct termios orig; void disableRawMode(); void enableRawMode(){ tcgetattr(STDIN_FILENO , &orig); atexit(disableRawMode); struct termios raw = orig; raw.c_lflag &= ~(ECHO | ICANON); tcsetattr(STDIN_FILENO , TCSAFLUSH, &raw); } void disableRawMode(){ tcsetattr(STDIN_FILENO , TCSAFLUSH ,&orig); } int main() { enableRawMode(); char c; while (read(STDIN_FILENO, &c, 1) == 1 && c != 'q') { if(iscntrl(c)){ printf("%d\n", c); }else{ printf("%d ('%c')\n", c, c); } } return 0; }
همانطور که می بینید دو هدر ctype برای تابع iscntrl و هدر stdio برای تابع printf به برنامه اضافه شد.
تابع iscntrl چک می کند آیا کاراکاتر داده شده یک کاراکتر کنترلی هست (درست بر می گرداند/ غیر صفر) یا یک کاراکتر printable (قابل چاپ).
کد های اسکی بین ۰-۳۱ کاراکتر های کنترلی هستند و کد های بین ۳۲ تا ۱۲۶ کاراکتر های قبل چاپ. البته کاراکتر ۱۲۷ هم کاراکتر کنترلی هست.
تابع printf هم که دیگر نیاز به گفتن ندارد. دارد؟
این یک برنامه خیلی کارآمد هست که به ما نشان می دهد چطوری کلید فشرده شده به بایت هایی تبدیل می شود که ما می خوانیم.
بیشتر کلید های معمولی مستقیما به کاراکتری تبدیل می شوند که نشان می دهند (علامت کاراکتر روی صفحه کلید هست) اما این را روی کاراکتر مثل جهت ها (اهل بازی هستید؟) یا esc یا Backspace یا DEL انجام دهید. کلید ها رو با Ctrl
بهتر هست چند چیز را به یاد داشته باشید:
\033[1m
که اگر عدد ۳۳ رو از مبنای ۸ به مبنای ۱۰ بر گردانیم. به عدد ۲۷ خواهیم رسید که معادل ۲۷ هست.)
این به عنوان escape sequence شناخته می شود. همه escape sequence ها با ۲۷ یا ۰۳۳ یا 0x1b شروع می شود.
Backspace
is byte 127
. Delete
is a 4-byte escape sequence.الان می توانید برنامه را اجرا کنید. اما خواندن متن را از دست ندهید.
اگر در این حالت شما Ctrl+S رو فشار دهید، ترمینال یخ می زند. اطلاعات بیشتر اینجا برای خارج کردن از حالت یخ زده (آن را در دمای ۳۰۰ میلیون درجه سانتی گراد قرار دهید تا مستقیما از جامد به گاز تبدیل شود | میعاناش کنید) کلید Ctrl+Q را فشار دهید. البته بعد از فشار دادن دکمه Ctrl+Q کلیدهایی که بعد از Ctrl+S به برنامه پاس داده شدند نیز چاپ می شوند.
این هم از متن با ترجمه اش در پایین:
Also, if you press Ctrl-Z
(or maybe Ctrl-Y
), your program will be suspended to the background. Run the fg
command to bring it back to the foreground. (It may quit immediately after you do that, as a result of read()
returning -1
to indicate that an error occurred. This happens on macOS, while Linux seems to be able to resume the read()
call properly.)
همچنین اگر کلید های Ctrl+Z (شاید Ctrl+Y باشد) را فشار دهید، برنامه به background می رود.
دستور fg رو اجرا کنید تا به foreground بر گردد.
بدرود