Op deze website gebruiken we cookies om content en advertenties te personaliseren, om functies voor social media te bieden en om ons websiteverkeer te analyseren. Ook delen we informatie over uw gebruik van onze site met onze partners voor social media, adverteren en analyse. Deze partners kunnen deze gegevens combineren met andere informatie die u aan ze heeft verstrekt of die ze hebben verzameld op basis van uw gebruik van hun services. Meer informatie.

Akkoord

Vraag & Antwoord

OS Linux

C vraag : Pipe redirect input / output.

Pinky & The Brain
8 antwoorden
  • Hallo,

    Ik weet niet zeker of ik deze vraag in het linuxforum dien te stellen of dat het toch onder programeren valt, maar ik denk dat het meer raakvlakken met linux heeft vanwege het linux OS waarop ik dit probeer.

    Ik was bezig met simpel c programmaatje dat bepaalde karakters uit een txt-file kan filteren.
    Nu ben ik geen ster in programeren en c ken ik eigenlijk niet, maar het is me wel gelukt :-).

    Momenteel run ik het programma als volgt :
    [code:1:5c63bb6bc2]knip bestandsnaam1 bestandsnaam2[/code:1:5c63bb6bc2]
    Knip is de naam van het programma en de 1ste parameter is het bronbestand en de 2e parameter is het doelbestand.

    Nu wil ik het echter ook eens met redirecting poberen (althans, ik denk dat het redirecting wordt genoemd ?).
    Dus dan wordt de aanroep :
    [code:1:5c63bb6bc2]knip < bestand1 > bestand2[/code:1:5c63bb6bc2]
    Dit is dus een pipe form volgens mij en ik weet wel dat dit reuze handig kan zijn, want zo kun je zonder tijdelijke bestanden input / output tussen programma's uitwisselen, maar ik weet niet precies hoe dit gaat.
    In mijn werkende programma kan ik simpel het bestand met de 1e parameter-bestandsnaam inlezen en verwerken.
    Hoe gaat dit echter met een een redirect ?
    Heb je dan een stream van char's die je moet afvangen of werkt heel het anders ?

    P&B
  • Herschrijf je proggie zo, dat je
    a) je input niet vanaf een file inleest, maar vanaf het keyboard.

    fgets( filedesc, &string ); wordt dus: gets (&string);
    ch = getc(filedesc) ; wordt dus ch = getchar();
    Zo heeft elke input routine voor files een equivalent die vanaf keyboard leest.

    en b)
    je output niet naar een file schrijft, maar op het scherm.

    fprintf( filedesc," ouptput" ); wordt: printf( "output" );
    etc.

    Als je je proggie start als
    $ proggie
    dan leest het dus input vanaf keyboard en voert de output uit op het scherm.

    $ proggie < inputfile > outputfile
    zal de input lezen vanaf inputfile en de output uitvoeren naar outputfile.

    $ proggie < inputfile
    en
    $proggie > outputfile
    lijkt me duidelijk.

    Zorg dat in je proggie duidelijk is wanneer het afgelopen is, anders blijft het eindeloos op input wachten….

    Ook dit is leuk:
    $ proggie < inputfile > outputfile 2>&1
    zet ook eventuele foutmeldingen in het file outputfile.
    Dit is makkelijk als je het proggie off screen wil draaien.
    Als je dat 2>&1 er niet bij zet komen de foutmeldingen op het scherm te staan.

    Hoop maar dat e.e.a. duidelijk is voor je, vraag anders maar.
    Douwe.
  • Ja, dit maakt het zeker duidelijker…nu kan snap ik dat pipen ook veel beter, dat vond ik hiervoor nogal lastig om voor te stellen.
    Dit is echt mooi :D, ik begin steeds meer van die prachtige shell mogelijkheden te ontdekken :).
    Nu is de grootste uitdaging om dit weer in C te vertalen ;-).
    Oh ja…de stop conditie…hoe gaat dat dan ?
    Nu jas ik gewoon door een tekstfile tot ik aan het eind ben….hoe weet je wanneer deze input (stream ?) op zijn eind is ?

    P&B
  • [quote:f071b6846b="Pinky & The Brain"]Ja, dit maakt het zeker duidelijker…nu kan snap ik dat pipen ook veel beter, dat vond ik hiervoor nogal lastig om voor te stellen.
    Dit is echt mooi :D, ik begin steeds meer van die prachtige shell mogelijkheden te ontdekken :).
    P&B[/quote:f071b6846b]
    thanks
    [quote:f071b6846b="Pinky & The Brain"]Nu is de grootste uitdaging om dit weer in C te vertalen ;-).
    Oh ja…de stop conditie…hoe gaat dat dan ?
    Nu jas ik gewoon door een tekstfile tot ik aan het eind ben….hoe weet je wanneer deze input (stream ?) op zijn eind is ?

    P&B[/quote:f071b6846b]

    Het makkelijks is een soort "stopwoord" te definieren in je programma en daarop je input te testen.

    Er is ook een routine feof( filedesc);
    $ man feof

    maar of feof( stdin ) lekker werkt moet je maar uitproberen.
  • YES !

    Eindelijk werkt het ! :)

    Het koste me nogal wat moeite, want ik ken helemaal geen c, maar na veel proberen en lezen heb ik nu toch een werken c script wat de goede output geeft ! :-)
    Er zullen vast wel enkele grove fouten / nalatigheden inzitten, maar het resultaat is zoals ik dat graag wenste.
    Achteraf bleek dat ik slechts op 2 plaatsen mijn code hoefde aan te passen, ik had slechts de file in- & output hoeven veranderen in stdin en stdout ;-).
    Nu is de code extreem gereduceerd, aangezien ik nu niet al die file controles hoef uittevoeren, ik had eerst bijna 40 regels…ach, het stelt misschien niets voor, maar om met c tebeginnen is het toch wel een goede oefening dacht ik :).

    [code:1:f017d4de53]
    /*
    Test programma dat een windows tekstbestand omzet naar een linux tekstbestand.
    Aan het eind van elke regel gebrukt linux het linefeed karakter om de aan te geven dat er naar de volgende regel moet worden gesprongen.
    Windows gebruikt echter nog een extra karakter, namelijk de cariage-return.
    Deze cariage return is in een windows tekstbestand zichtbaar als een ^M (karakter 13) aan het eind van elke regel.
    */

    #include <stdio.h>

    int main()
    {
    int value;
    printf("Bezig…
    ");
    do
    {
    value = fgetc(stdin);
    if (value >= 0)
    {
    if (value != 13)
    fputc(value, stdout);
    }
    } while (value >= 0);

    printf("Klaar !
    ");
    return 0;
    }
    [/code:1:f017d4de53]

    Als je zo bezig bent verken je mooi je systeem en ga je pas echt beseffen hoe mooi linux is…zoveel verborgen mogelijkheden…:-)

    Bedankt Douwe ! :)

    P&B
  • Even kleine aanmerking; vergeet niet dat je "Bezig…" ook in de output op stdout terecht komt. Schrijf die liever naar stderr.
    Succes verder!
  • Crap, je hebt gelijk :oops: , dat moet idd anders :lol:

    P&B

    <edit>
    Ik heb het veranderd in :
    [code:1:63406ceabf]
    fputs("Bezig…
    ", stderr);
    en
    fputs("Klaar !
    ", stderr);
    [/code:1:63406ceabf]
    Dat wordt ook gewoon in de console weergegeven (wordt dit nu ook gelogd ?), maar is komt niet in de output terecht :-)

    Bedankt !
    </edit>
  • Zonde dat je code weggepleurt hebt om uit een betand te lezen. Onder Unix zijn "stdin" en "stdout" gewoon file descriptors. Je kunt dus gewoon "echte file descriptors" gebruiken, en als er geen bestanden als parameters gegeven zijn in plaats daarvan daarvan stdin en stdout gebruiken.

    En omdat file descriptors gewoon ints zijn, kun je op een gegeven moment gewoon stdin aan een variabele toewijzen, zodat het voor de rest van het programma niet uitmaakt of het om bestanden of stdin/stdout gaat.

Beantwoord deze vraag

Dit is een gearchiveerde pagina. Antwoorden is niet meer mogelijk.