{"id":5259,"date":"2022-03-26T00:01:08","date_gmt":"2022-03-26T07:01:08","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=5259"},"modified":"2022-03-19T09:46:16","modified_gmt":"2022-03-19T16:46:16","slug":"accessing-the-printer-in-c","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=5259","title":{"rendered":"Accessing the Printer in C"},"content":{"rendered":"<p>Back in the old days, the printer was a device wired to the computer and handled directly by whatever program wanted to use it. Printing in C involved opening the printer device and sending the data. Today, things work differently.<br \/>\n<!--more--><br \/>\nAll printing is now managed by the operating system. In Linux, while the printer might be accessible as a file located in the <code>\/dev<\/code> directory, it could also be a network device. Regardless, the operating system is the printer&#8217;s commanding officer. To  write C code that sends something to the printer requires a study of the operating system&#8217;s Application Programming Interface (API). The approach is different for each operating system.<\/p>\n<p>Yet, all hope isn&#8217;t lost.<\/p>\n<p>The trick I use to print from C is to piggyback on another program that handles the printing job for me. After all, why re-invent the wheel?<\/p>\n<p>In this case, the program is <em>lp<\/em>, a command line tool that prints in the Linux\/Unix\/macOS universe. If <em>lp<\/em> isn&#8217;t installed for your distro, use the OS package manager to obtain it. Alas, Windows lacks such a tool, so this lesson is primarily targeted to the Unix\/Linux environment.<\/p>\n<p>I suppose you could spawn the <em>lp<\/em> program to handle the printing task, but an easier approach is to open the program as a process. To perform this feat, use the <em>popen()<\/em> function, which I wrote about in <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=1418\">a previous Lesson<\/a>. Here&#8217;s the statement:<\/p>\n<p><code>printer = popen(\"lp\",\"w\");<\/code><\/p>\n<p>The <em>popen()<\/em> function opens the program <em>lp<\/em> for writing, <code>\"w\"<\/code>. The return value is a <code>FILE<\/code> handle, <code>printer<\/code>. You can then use standard file I\/O functions to print data, as the following code demonstrates:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2022_03_26-Lesson.c\" rel=\"noopener\" target=\"_blank\">2022_03_26-Lesson.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n\r\nint main()\r\n{\r\n    FILE *printer;\r\n\r\n    printer = popen(\"lp\",\"w\");\r\n    if( printer==NULL )\r\n    {\r\n        fprintf(stderr,\"Unable to open `lp`\\n\");\r\n        return(1);\r\n    }\r\n\r\n    fprintf(printer,\"Hello, Mr. Printer!\\n\");\r\n\r\n    pclose(printer);\r\n    return(0);\r\n}<\/pre>\n<p>Line 7 opens the <em>lp<\/em> program for input (writing). Line 8 confirms that the process opened successfully. If not, the program spews forth an error message and dies.<\/p>\n<p>At Line 14, the <em>fprintf()<\/em> function sends a string of text to the printer; this program&#8217;s output becomes the <em>lp<\/em> program&#8217;s input.<\/p>\n<p>Line 16 closes the process, signaling to the <em>lp<\/em> program that input is done. The <em>lp<\/em> program then ejects the page.<\/p>\n<p>If only things were as uncomplicated in Windows.<\/p>\n<p>A long time ago, Windows (and DOS before it) used the <code>PRN<\/code> device to represent the primary printer. You could also use <code>LPT1<\/code>, the computer&#8217;s first parallel port. Opening one of these devices as a file worked the same as opening any file. Once opened, you used standard file I\/O commands to send information to the printer. In fact, I once used this command line to eject a sheet of paper:<\/p>\n<p><code>echo ^L > prn<\/code><\/p>\n<p>The control-L code ejects a page, even on today&#8217;s printers. But this command no longer works in Windows, neither does attempting to open the PRN device in your C programs.<\/p>\n<p>Again, if you want to code for the printer directly in C, you must use the operating system&#8217;s API. This information is widely available, but specific to the given operating system.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Printers are an operating system thing, though it&#8217;s still possible to write C code that sends output to a printer. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=5259\">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-5259","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\/5259","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=5259"}],"version-history":[{"count":5,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/5259\/revisions"}],"predecessor-version":[{"id":5266,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/5259\/revisions\/5266"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5259"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=5259"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=5259"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}