{"id":6305,"date":"2024-03-30T00:01:47","date_gmt":"2024-03-30T07:01:47","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=6305"},"modified":"2024-04-06T10:39:11","modified_gmt":"2024-04-06T17:39:11","slug":"looking-for-a-keyboard-hit","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=6305","title":{"rendered":"Looking for a Keyboard Hit"},"content":{"rendered":"<p>The C language is famously platform independent. This feature may seem unimportant these days, but back in the early computer era having a language you code code on multiple systems was key to the C language&#8217;s success. This benefit may be one reason why C lacks a specific function to check on the keyboard status to determine whether a key has been pressed. Such a function is hardware-dependent.<br \/>\n<!--more--><br \/>\nEven so, C does have a function that lets you plumb the depths of a specific piece of hardware. It&#8217;s the mysterious and often feared function <em>ioctl()<\/em>. Rather than struggle to pronounce it, consider it as the Input\/Output Control function.<\/p>\n<p>I&#8217;ve <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=5730\">written about<\/a> the <em>ioctl()<\/em> function before, specifically with regards to counting the number of lines and columns on the terminal window. The function gathers information about a file descriptor. Like the terminal, standard input is also a file descriptor.<\/p>\n<p>One of the aspects of the standard input file descriptor is counting the number of characters waiting in the input queue. In other words, keyboard input that has yet to be read. (And, yes, I know that standard input can also come from another source, but this Lesson is focusing on the keyboard.)<\/p>\n<p>The specific statement is:<\/p>\n<p><code>ioctl(STDIN_FILENO,FIONREAD,&k);<\/code><\/p>\n<p>The <em>ioctl()<\/em> function reads file descriptor zero for standard input using the <code>STDIN_FILENO<\/code> defined constant (<code>unistd.h<\/code>). This constant is a file descriptor data type; the <em>stdin<\/em> constant for standard input is a <code>FILE*<\/code> data type, not a file descriptor. The <code>FIONREAD<\/code> defined constant represents input characters waiting to be read. The final argument is the address of an integer to hold the count of input characters in the queue.<\/p>\n<p>Traditionally in C programming, the function that checks on waiting characters for the keyboard is named <em>kbhit()<\/em>. This name was used in the old Borland TurboC programming language, and I believe it&#8217;s used in C++.<\/p>\n<p>The following code updates the busy-loop presented in <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=6304\">last week&#8217;s Lesson<\/a>, adding the <em>kbhit()<\/em> function to keep the loop spinning while still checking on a key press.<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2024_03_30-Lesson.c\" rel=\"noopener\" target=\"_blank\">2024_03_30-Lesson.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;sys\/ioctl.h&gt;\r\n#include &lt;unistd.h&gt;\r\n\r\nint kbhit(void)\r\n{\r\n    int k;\r\n\r\n    ioctl(STDIN_FILENO,FIONREAD,&amp;k);\r\n\r\n    return(k);\r\n}\r\n\r\nint main()\r\n{\r\n    char a;\r\n\r\n    a = 'A';\r\n    while(1)\r\n    {\r\n        printf(\" %c\",a++);\r\n        if( a=='Z' )\r\n            a = 'A';\r\n        <span class=\"comments\">\/* terminate on key *\/<\/span>\r\n        if( kbhit() )\r\n        {\r\n            getchar();\r\n            break;\r\n        }\r\n    }\r\n\r\n    return 0;\r\n}<\/pre>\n<p>The <em>kbhit()<\/em> function reads the status of the standard input device, which can be assumed to be the keyboard. The number of characters waiting to be read is stored in variable <code>k<\/code> and returned.<\/p>\n<p>In the <em>main()<\/em> function, the <em>while<\/em> loop outputs letters of the alphabet repeatedly from A through Z. The <em>kbhit()<\/em> function is called in an <em>if<\/em> test. When the function returns zero (meaning no key has been pressed), the <em>if<\/em> test fails and the loop continues.<\/p>\n<p>When a key is waiting, the <em>kbhit()<\/em> function returns a TRUE value. The value indicates the number of characters to read, but that&#8217;s not important. Upon triggering a TRUE condition for the <em>if<\/em> statement, a character is read and the loop breaks. The program ends.<\/p>\n<p>For sample output, the program spews the alphabet until you tap a key on the keyboard. then the keyboard&#8217;s input queue is read. Or, more specifically, the standard input queue is read.<\/p>\n<p>Network programming also involves polling for input. Open network sockets are listened to similar to the way this lesson&#8217;s program listens to standard input. In <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=6321\">next week&#8217;s Lesson<\/a>, I continue my exploration of polling techniques by apply a technique used to read sockets for pending network input to the sample keyboard input program.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Checking to see whether a character is waiting in the queue requires using a secret and scary function. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=6305\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-6305","post","type-post","status-publish","format-standard","hentry","category-main"],"_links":{"self":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/6305","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=6305"}],"version-history":[{"count":8,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/6305\/revisions"}],"predecessor-version":[{"id":6354,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/6305\/revisions\/6354"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=6305"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=6305"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=6305"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}