Nieuws:

Welkom, Gast. Alsjeblieft inloggen of registreren.
Heb je de activerings-mail niet ontvangen?

Auteur Topic: [C] Tekens naar printer schrijven met CUPS  (gelezen 3973 keer)

Offline Joshua822

  • Lid
[C] Tekens naar printer schrijven met CUPS
« Gepost op: 2009/09/04, 19:36:41 »
Hallo allemaal.

Ik probeer mijn oude programma om bestanden te lezen uit te breiden. Ik wil dat het mogelijk is het bestand ook uit te printen.

Allereerst, ik heb de informatie van deze pagina, van de sectie "7.6 afdrukken naar de printer". Om naar de printer te schrijven zou ik dus naar het bestand "PRN" moeten schrijven. Dat doe ik dus. Er komt netjes een bestand "PRN" met als inhoud de tekens die naar de printer moesten worden geschreven worden in de zelfde map als het programma. Maar dat is niet de bedoeling.

Daarom is de vraag, naar welk bestand moet ik schrijven om te printen, of doe ik het helemaal verkeerd ? Ik heb de volgende bestanden al met hetzelfde resultaat geprobeerd : LPT, LPT1, LPT2, stdprn.

Hier is mijn code:
#include <stdio.h>
#include <stdlib.h>

int main ( int argc, char * argv[] )
{
   if ( argc != 2 )
   {
     printf("U specificeerde geen bronbestand. \n");
     return 1;
   }
   FILE *fptr = fopen ( argv[1], "r" );
   FILE *printer = fopen ( "PRN", "w");
   signed int teken, printok;
   if ( fptr == NULL )
   {
     printf("Het opgegeven bestand bestaat niet. \n");
     return 1;
   }
   printf ( "Wilt u het bestand ook uitprinten?: y / n: " );
   scanf ( "%d", &printok );
   switch ( printok )
   {
     case 121:
       printok = 1;
       break;
     default:
       printok = 0;
   }
   if ( printok == 1 )
     do
     {
       teken = getc ( fptr );
       if ( teken != EOF )
       {
         putchar ( teken );
         putc( teken, printer );
       }
     } while ( teken != EOF );
   else
   {
     do
     {
       teken = getc ( fptr );
       if ( teken != EOF )
         putchar ( teken ); 
     } while ( teken != EOF );
   }
   fclose ( fptr );   
   fclose ( printer );
   return 0;
}

Alvast bedankt.
« Laatst bewerkt op: 2009/09/05, 12:28:15 door Joshua822 »

Offline profoX

  • Lid
    • wesley
    • Lionslink
Re: [C] Tekens naar printer schrijven
« Reactie #1 Gepost op: 2009/09/04, 19:46:36 »
Voor zover ik weet is "printen naar een printer" geen standaardfeature van ANSI C. Je hebt hiervoor dus een extra library nodig.
Human Knowledge Belongs To The World -- Antitrust (2001)
Nederlandstalige Ubuntu documentatie van Ubuntu-NL (wiki)

Offline Joshua822

  • Lid
Re: [C] Tekens naar printer schrijven
« Reactie #2 Gepost op: 2009/09/04, 19:51:54 »
Voor zover ik weet is "printen naar een printer" geen standaardfeature van ANSI C. Je hebt hiervoor dus een extra library nodig.

Weet je ook welke? In ieder geval, denk ik niet dat het met stdio.h of stdlib.h gaat lukken.

Offline profoX

  • Lid
    • wesley
    • Lionslink
Re: [C] Tekens naar printer schrijven
« Reactie #3 Gepost op: 2009/09/04, 19:59:36 »
Ik denk niet dat er een low-level text printing library voor bestaat...

Ik heb gekeken hoe de Qt C++ toolkit een printer aanstuurt, en dat is als volgt:

Citaat
When printing directly to a printer on Windows or Mac OS X, QPrinter uses the built-in printer drivers. On X11, QPrinter uses the Common Unix Printing System (CUPS) or the standard Unix lpr utility to send PostScript or PDF output to the printer. As an alternative, the printProgram() function can be used to specify the command or utility to use instead of the system default.

Dus het is erg systeemafhankelijk. Als jouw programma alleen op Linux moet draaien zou je dus eens naar lpr en CUPS kunnen kijken.
Human Knowledge Belongs To The World -- Antitrust (2001)
Nederlandstalige Ubuntu documentatie van Ubuntu-NL (wiki)

Offline Joshua822

  • Lid
Re: [C] Tekens naar printer schrijven
« Reactie #4 Gepost op: 2009/09/04, 20:03:34 »
Het programma hoeft inderdaad alleen op Linux te draaien, want dat is het enige dat ik heb :P

Maar zijn die functies afhankelijk van C++ / Qt, zo ja, dan heb ik er weinig aan. Of ik zou twee programma's moeten schrijven, een voor het lezen in C, en een voor het printen in C++, maar dat lijkt me niet ideaal.

Google levert trouwens tot nu toe geen uitkomst.

Offline profoX

  • Lid
    • wesley
    • Lionslink
Re: [C] Tekens naar printer schrijven
« Reactie #5 Gepost op: 2009/09/04, 20:08:22 »
Het programma hoeft inderdaad alleen op Linux te draaien, want dat is het enige dat ik heb :P

Maar zijn die functies afhankelijk van C++ / Qt, zo ja, dan heb ik er weinig aan. Of ik zou twee programma's moeten schrijven, een voor het lezen in C, en een voor het printen in C++, maar dat lijkt me niet ideaal.

Google levert trouwens tot nu toe geen uitkomst.
CUPS en lpr zijn Linux-specifieke printsystemen. Heeft opzich niets met C of C++ te maken, maar er bestaat vast wel een API om CUPS aan te sturen vanuit C.
Human Knowledge Belongs To The World -- Antitrust (2001)
Nederlandstalige Ubuntu documentatie van Ubuntu-NL (wiki)

Offline profoX

  • Lid
    • wesley
    • Lionslink
Re: [C] Tekens naar printer schrijven
« Reactie #6 Gepost op: 2009/09/04, 20:10:20 »
Misschien helpt dit je op weg: http://www.cups.org/documentation.php/doc-1.4/api-cups.html

edit: maar misschien is het omzetten van je tekst naar postscript en vervolgens lpr (of iets dergelijks) als commando aanroepen vanuit C wel wat handiger
« Laatst bewerkt op: 2009/09/04, 20:14:50 door profoX »
Human Knowledge Belongs To The World -- Antitrust (2001)
Nederlandstalige Ubuntu documentatie van Ubuntu-NL (wiki)

Offline Joshua822

  • Lid
Re: [C] Tekens naar printer schrijven
« Reactie #7 Gepost op: 2009/09/04, 20:20:22 »
Bedankt. Dat zal ik eens rustig doornemen. Ik post het wel als ik meer hulp nodig heb ;)

Offline track

  • Lid
Re: [Tijdelijk opgelost][C] Tekens naar printer schrijven
« Reactie #8 Gepost op: 2009/09/05, 03:14:04 »
Hoi Joshua,

die PRN, LPT, STDOUT enz. zijn de DOS- toestellen toch ?
Bij alles vanuit dat kader werkt het uiteraard.

Bij Linux zijn de toestellen de  /dev/lp0 ,   /dev/stdout ,  /dev/stderr  enz.
(een ls -l /dev  verklapt je wat er allemaal is ..)
Je moet er wél kijken welke rechten je hebt, maar dan kun je ook naar die
"ruwe" toestellen schrijven.  (je moet wél weten wat je doet ..)

Ik maak er gebruik van bij CL scriptjes als ik iets naar de  "stderr" schrijf:
stderr="/dev/stderr"                         # gemakshalve een variabele in de header, dan hoef ik minder te typen
printf "Dat was nou fout !\n" > $stderr      # en dan komt het waar het hoort
Dit werkt ook uitstekend om een console vanaf een andere aan te sturen (  >> "/dev/tty2" ).

Bij de printer durf ik dat trouwens (nog) niet, maar met een  lp 
kun je ook al ruwe stuurtekens naar de printer sturen ...

track

Offline Joshua822

  • Lid
Re: [Tijdelijk opgelost][C] Tekens naar printer schrijven
« Reactie #9 Gepost op: 2009/09/05, 09:19:20 »
Bedankt voor je antwoord Track.

Dus, als het goed is kan ik dit compileren en uitvoeren zonder dat mijn printconfiguratie "CrunchBang" doet:
#include <stdio.h>
#include <stdlib.h>

int main ( int argc, char * argv[] )
{
   if ( argc != 2 )
   {
     printf("U specificeerde geen bronbestand. \n");
     return 1;
   }
   FILE *fptr = fopen ( argv[1], "r" );
   FILE *printer = fopen ( "/dev/lp0", "a");
   signed int teken, printok;
     
   if ( fptr == NULL )
   {
     printf("Het opgegeven bestand bestaat niet. \n");
     return 1;
   }
   printf ( "Wilt u het bestand ook uitprinten?: y / n: " );
   scanf ( "%d", &printok );
   switch ( printok )
   {
     case 121:
       printok = 1;
       break;
     default:
       printok = 0;
   }
   if ( printok == 1 )
     do
     {
       teken = getc ( fptr );
       if ( teken != EOF )
       {
         putchar ( teken );
         puitc ( printer );
       }
     } while ( teken != EOF );
   else
   {
     do
     {
       teken = getc ( fptr );
       if ( teken != EOF )
         putchar ( teken ); 
     } while ( teken != EOF );
   }
   fclose ( fptr );   
   fclose ( printer );
   return 0;
}


Offline profoX

  • Lid
    • wesley
    • Lionslink
Re: [Tijdelijk opgelost][C] Tekens naar printer schrijven
« Reactie #10 Gepost op: 2009/09/05, 10:17:40 »
Dat zal echter niet voor alle printers werken...
Human Knowledge Belongs To The World -- Antitrust (2001)
Nederlandstalige Ubuntu documentatie van Ubuntu-NL (wiki)

Offline Joshua822

  • Lid
Re: [C] Tekens naar printer schrijven met CUPS
« Reactie #11 Gepost op: 2009/09/05, 12:34:50 »
Inderdaad, die oplossing werkte hier niet.

Ik heb echter wel een paar vraagjes over CUPS waar ik geen duidelijkheid over krijg.

1) Moet ik zelf een connectie leggen met de server? Of kan ik direct opdrachten geven aan de server met cups/cups.h?
2) Waarvoor dient de num_dests variabel?
3) Welke argumenten hebben de functies CupsGetDest en CupsGetDests?

Dat zijn alle onduidelijkheden tot nu toe. Alvst bedankt.

Offline track

  • Lid
Re: [C] Tekens naar printer schrijven met CUPS
« Reactie #12 Gepost op: 2009/09/05, 12:46:44 »
Nee, dit zal inderdaad niet lukken:
FILE *printer = fopen ( "/dev/lp0", "a");en de CL verklapt je ook waarom:
track@ubuntu:~$ cat x.txt > /dev/lp0
bash: /dev/lp0: Permission denied
track@ubuntu:~$ ls -l /dev/lp0
crw-rw---- 1 root lp 6, 0 2009-09-05 12:23 /dev/lp0
Je hebt gewoon niet de rechten ervoor !
En dat is standaard ingesteld opdat niemand jouw printer kan verminken.

Dus, zo makkelijk kan het niet.

track

p.s.: wat wél werkt is dit:
cat x.txt | lp
« Laatst bewerkt op: 2009/09/05, 12:54:45 door track »

Offline Joshua822

  • Lid
Re: [C] Tekens naar printer schrijven met CUPS
« Reactie #13 Gepost op: 2009/09/05, 12:54:29 »
Eigenlijk wel. Ik heb het programma ook als sudo uitgevoerd en toen kreeg ik geen foutmelding.

Offline profoX

  • Lid
    • wesley
    • Lionslink
Re: [C] Tekens naar printer schrijven met CUPS
« Reactie #14 Gepost op: 2009/09/05, 12:56:45 »
Ik heb geen ervaring met low-level CUPS en kan het ook niet testen aangezien ik geen printer heb :)

1) Voor zover ik de API heb ingekeken vermeld de http_t struct variabele die je in vele function calls meegeeft de server connectie, en je kan de constante CUPS_HTTP_DEFAULT hiervoor gebruiken.

2) Als je verwijst naar "int num_dests = cupsGetDests(&dests);" dan bevat num_dests het aantal printers dat geconfigureerd is volgens mij.

3) http://www.cups.org/documentation.php/doc-1.4/api-cups.html#cupsGetDest / http://www.cups.org/documentation.php/doc-1.4/api-cups.html#cupsGetDests

Misschien is het wel beter om een andere meer high-level wrapper rond CUPS e.d. te vinden, bijvoorbeeld de GTK+ printing API - http://library.gnome.org/devel/gtk/unstable/GtkPrintJob.html - je hebt dan wel een GTK+ dependency... en ik weet niet of dat deftig werkt op alle systemen.
Human Knowledge Belongs To The World -- Antitrust (2001)
Nederlandstalige Ubuntu documentatie van Ubuntu-NL (wiki)

Offline jimi

  • Lid
Re: [C] Tekens naar printer schrijven met CUPS
« Reactie #15 Gepost op: 2009/09/05, 22:21:06 »
Rechtstreeks schrijven naar /dev/lp0 is af te raden: Ten eerste werkt het niet als gewone gebruiker, daarnaast maak je zo geen gebruik van de printer-wachtrij, waardoor het fout gaat als er al een ander document aan het printen was.

Aan de code van Joshua822 te zien gaat het hier om een command-line programma. Het simpelste is dan - zoals track ook al zegt - om /usr/bin/lp uit te voeren. Dat werkt op praktisch elke Unix, en je introduceert geen dependencies van Qt of GTK.

Onderstaand voorbeeldje start /usr/bin/lp als childproces en stuurt "Hello, world!" daarheen via een pipe.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

int main (int argc, char *argv[])
{
        char buf[1024];
        int p[2];
        pipe(p);

        if (fork()) /* parent */
        {
                close(p[0]);
                strcpy (buf, "Hello, world!\n");
                write(p[1], buf, strlen(buf));
        }
        else { /* child */
                dup2(p[0], 0); /* stdin is now read from pipe */
                close(p[0]);
                close(p[1]);
                execl("/usr/bin/lp", "lp", NULL);
        }
        return 0;
}