creating a testfile for catv

Discussion in 'C Programming' started by c gordon liddy, Mar 30, 2008.

  1. What follows purports to be a soln for K&R 8-1 that prints bitshifted
    control chars and non-ascii chars:

    #include <stdio.h>

    int main(int argc, char **argv)
    {

    FILE *fp;
    void filecopy(FILE *, FILE *);

    if (argc < 2) printf("die");
    else
    while (--argc > 0)
    if ((fp = fopen(*++argv, "r")) == NULL)
    {
    printf("catv can't open %s\n", *argv);
    return 1;
    }
    else
    {
    filecopy(fp, stdout);
    fclose(fp);
    }

    return 0;
    }

    /*filecopy */
    void filecopy(FILE *ifp, FILE *ofp)
    {
    int c;
    int ch;
    int result;

    while((ch=getc(ifp)) != EOF)
    {
    if (iscntrl(ch)) {
    /* ch is a control character */
    int result;

    /*
    * The two characters we want to print. The first is '^';
    * we don't know yet what the second is.
    */
    int ch1 = '^';
    int ch2;

    /* Try to print the first character. */
    result = putchar(ch1);
    if (result == EOF) {
    /* Failed, terminate the loop */
    break;
    }

    if (ch == '\177') {
    /* ch is DEL, we want "^?" */
    ch2 = '?';
    }
    else {
    /*
    * ch is another control character.
    * Transform 1 to 'A', 2 to 'B', etc. using
    * our intimate knowledge of ASCII encoding.
    */
    ch2 = ch | 0100;
    }

    /* Print as above */
    result = putchar(ch2);
    if (result == EOF) {
    break;
    }
    }

    else putc(ch, ofp);



    }

    }
    // gcc -o catv catv4.c
    // catv text24.txt >text43.txt

    Abridged output from text43 is:
    ^JTarget: i386-pc-mingw32^J

    My guess is that J is what you get when you add octal 0100 to a carriage
    return. Am I correct to think that the first 32 chars are control chars?
    DEL appears to be 117 as well.

    How would I populate a file containing non-ascii and ctrl chars for test
    purposes? (Does anyone have one?)
    --
    C. Gordon Liddy

    "Virile, vigorous, potent"
     
    c gordon liddy, Mar 30, 2008
    #1
    1. Advertising

  2. c gordon liddy

    santosh Guest

    c gordon liddy wrote:

    <snip>

    > How would I populate a file containing non-ascii and ctrl chars for
    > test purposes? (Does anyone have one?)


    The easiest way is to open the file in a hex editor and fill in the
    character codes directly.
     
    santosh, Mar 30, 2008
    #2
    1. Advertising

  3. On Sun, 30 Mar 2008 02:22:25 -0700, c gordon liddy wrote:

    > What follows purports to be a soln for K&R 8-1 that prints bitshifted
    > control chars and non-ascii chars:

    [snippage]
    > How would I populate a file containing non-ascii and ctrl chars for test
    > purposes? (Does anyone have one?)


    mkchars.c:

    #include "stdio.h"

    unsigned char i;

    int main(int argc, char * argv[])
    {
    unsigned char buffer[256];
    do { buffer = i; } while(++i);
    fwrite(buffer, 256, 1, stdout);

    return 0;
    }

    make mkchars
    ../mkchars >samplechars

    ../catv samplechars


    Many terminal emulators will react oddly if you fail to redirect. Don't
    ../mkchars

    Many editors will behave badly if you try to edit samplechars.

    Martin
    --
    Martin Golding DoD #0236 |
    Always code as if the person who ends up maintaining your code will be a
    violent psychopath who knows where you live.
    y
     
    Martin Golding, Mar 30, 2008
    #3
  4. c gordon liddy

    santosh Guest

    Martin Golding wrote:

    > On Sun, 30 Mar 2008 02:22:25 -0700, c gordon liddy wrote:
    >
    >> What follows purports to be a soln for K&R 8-1 that prints bitshifted
    >> control chars and non-ascii chars:

    > [snippage]
    >> How would I populate a file containing non-ascii and ctrl chars for
    >> test purposes? (Does anyone have one?)

    >
    > mkchars.c:
    >
    > #include "stdio.h"


    ITYM <stdio.h>

    > unsigned char i;
    >
    > int main(int argc, char * argv[])
    > {
    > unsigned char buffer[256];
    > do { buffer = i; } while(++i);
    > fwrite(buffer, 256, 1, stdout);


    If the OP meant "ASCII control characters", then perhaps you should stop
    at 31?

    As far as "non-ascii" characters, I don't quite get what the OP means.
    Does he mean characters from other encodings, like extended ASCII,
    EBCDIC etc.?

    > return 0;
    > }
    >
    > make mkchars
    > ./mkchars >samplechars
    >
    > ./catv samplechars
    >
    >
    > Many terminal emulators will react oddly if you fail to redirect.
    > Don't ./mkchars
    >
    > Many editors will behave badly if you try to edit samplechars.
    >
    > Martin
     
    santosh, Mar 30, 2008
    #4
  5. Martin Golding <> writes:
    > On Sun, 30 Mar 2008 02:22:25 -0700, c gordon liddy wrote:
    >> What follows purports to be a soln for K&R 8-1 that prints bitshifted
    >> control chars and non-ascii chars:

    > [snippage]
    >> How would I populate a file containing non-ascii and ctrl chars for test
    >> purposes? (Does anyone have one?)

    >
    > mkchars.c:
    >
    > #include "stdio.h"
    >
    > unsigned char i;
    >
    > int main(int argc, char * argv[])
    > {
    > unsigned char buffer[256];
    > do { buffer = i; } while(++i);
    > fwrite(buffer, 256, 1, stdout);
    >
    > return 0;
    > }

    [...]

    Yes, that should do the job, but let me offer a few comments. None of
    these are actual errors, but they're ways in which your code could be
    made clearer.

    Use #include <stdio.h>, not #include "stdio.h".

    If you don't use argc or argv, you don't have to declare them; use
    "int main(void)".

    ``i'' is declared at file scope. Why? It's only used inside main(),
    so it should be declared inside main. Perhaps you declared it at file
    scope so it would be implicitly initialized to 0.

    Your "do ... while(++i);" depends on the value wrapping around from
    255 to 0. That works only if UCHAR_MAX==255, which is not guaranteed.
    Even if you're assuming 8-bit characters and don't care about
    portability to more exotic systems, I find it needlessly obscure. I'd
    probably use a for loop instead.

    You store all 256 characters in a buffer, then print the entire buffer
    at once. This is not necessary, since stdio does its own buffering.

    Here's how I'd probably write it:

    #include <stdio.h>
    int main(void)
    {
    int c;
    for (c = 0; c <= 255; c ++) {
    putchar(c);
    }
    return 0;
    }

    --
    Keith Thompson (The_Other_Keith) <>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Mar 30, 2008
    #5
  6. c gordon liddy

    Gerry Ford Guest

    "Martin Golding" <> wrote in message
    news:p...
    > On Sun, 30 Mar 2008 02:22:25 -0700, c gordon liddy wrote:
    >
    >> What follows purports to be a soln for K&R 8-1 that prints bitshifted
    >> control chars and non-ascii chars:

    > [snippage]
    >> How would I populate a file containing non-ascii and ctrl chars for test
    >> purposes? (Does anyone have one?)

    >
    > mkchars.c:
    >
    > #include "stdio.h"
    >
    > unsigned char i;
    >
    > int main(int argc, char * argv[])
    > {
    > unsigned char buffer[256];
    > do { buffer = i; } while(++i);
    > fwrite(buffer, 256, 1, stdout);
    >
    > return 0;
    > }
    >
    > make mkchars
    > ./mkchars >samplechars
    >
    > ./catv samplechars
    >
    >
    > Many terminal emulators will react oddly if you fail to redirect. Don't
    > ./mkchars
    >
    > Many editors will behave badly if you try to edit samplechars.

    Thanks Martin. You got me rolling with this, so I've got output to tune
    things up with.

    After I got a look at the output, I found a link that explained control and
    non-ascii chars:
    http://www.robelle.com/smugbook/ascii.html
    It looks like ascii chars are 0 through 127 decimal. Control chars include
    the first 32 and DEL at octal 177 (7 +8*7+64*1=7+56+64=127 decimal, the
    ultimate ascii char). I'm confused as to the taxonomy of chars between
    decimal 32 and decimal 37.

    My output with Martin's output catv'ed is:
    ^@^A^B^C^D^E^F^G^H^I^J^K^L^M^N^O^P^Q^R^S^T^U^V^W^X^Y
    , which is good, in that I seem to have the behavior for control chars
    correct. Clearly, other chars aren't making it through yet, so I need some
    more time at the chalkboard for that.

    I'll finish with Martin's output. All bets are off on how they are
    displayed on a usenet message:

    

    
    !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~?,f".??^?S<OZ''"".--~Ts>ozY
    ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ
    --

    c gordon liddy
     
    Gerry Ford, Mar 30, 2008
    #6
  7. C. Gordon Liddy said:

    <snip>

    > Current output with catv is:
    > the quick brown fox^J^@^A^B^C^D^E^F^G^H^I^J^K^L^M^N^O^P^Q^R^S^T^U^V^W^X^Y
    >
    > So after it reads and writes the control characters, it doesn't want to
    > print anything more.


    It is very suggestive that your output stops at Ctrl-Z, which is used as an
    end-of-text-file marker by some systems. The fix is obvious - open the
    file in binary mode:

    <snip>

    > #include <stdio.h>
    >
    > int main(int argc, char **argv)
    > {
    >
    > FILE *fp;
    > void filecopy(FILE *, FILE *);
    >
    > if (argc < 2) printf("die");
    > else
    > while (--argc > 0)
    > if ((fp = fopen(*++argv, "r")) == NULL)


    Change "r" to "rb" and re-test.

    <snip>

    --
    Richard Heathfield <http://www.cpax.org.uk>
    Email: -http://www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999
     
    Richard Heathfield, Mar 31, 2008
    #7
  8. "Keith Thompson" <> wrote in message
    news:...
    > Here's how I'd probably write it:


    > #include <stdio.h>
    > int main(void)
    > {
    > int c;
    > for (c = 0; c <= 255; c ++) {
    > putchar(c);
    > }
    > return 0;

    I modified this program and now have a good test file:

    #include <stdio.h>
    int main(void)
    {
    int c;
    printf ("the quick brown fox\n");
    for (c = 0; c <= 40; c ++) {
    putchar(c);
    }
    printf ("jumps over\n");
    for (c = 100; c <= 200; c ++) {
    putchar(c);
    }
    printf ("the lazy dog\n");
    return 0;
    }
    // gcc -o mkchars mkchars2.c
    // mkchars >text42.txt

    Current output with catv is:
    the quick brown fox^J^@^A^B^C^D^E^F^G^H^I^J^K^L^M^N^O^P^Q^R^S^T^U^V^W^X^Y

    So after it reads and writes the control characters, it doesn't want to
    print anything more. Here's the current version of catv. I cleaned up the
    bracing, thinking that that would be where I was in trouble, but that's not
    it. I also added some functionality for non-ascii chars. Again no luck.

    #include <stdio.h>

    int main(int argc, char **argv)
    {

    FILE *fp;
    void filecopy(FILE *, FILE *);

    if (argc < 2) printf("die");
    else
    while (--argc > 0)
    if ((fp = fopen(*++argv, "r")) == NULL)
    {
    printf("catv can't open %s\n", *argv);
    return 1;
    }
    else
    {
    filecopy(fp, stdout);
    fclose(fp);
    }

    return 0;
    }

    /*filecopy */
    void filecopy(FILE *ifp, FILE *ofp)
    {
    int c;
    int ch;
    int result;
    int ch1 = '^';
    int ch2;
    int ch3 = 'M';

    while((ch=getc(ifp)) != EOF)
    {
    if (iscntrl(ch))
    {

    result = putchar(ch1);
    if (result == EOF)
    {
    /* Failed, terminate the loop */
    break;
    }

    if (ch == '\177')
    {
    /* ch is DEL, we want "^?" */
    ch2 = '?';
    }
    else
    {
    /*
    * ch is another control character.
    * Transform 1 to 'A', 2 to 'B', etc. using
    * our intimate knowledge of ASCII encoding.
    */
    ch2 = ch | 0100;
    }

    /* Print as above */
    result = putchar(ch2);
    if (result == EOF)
    {
    break;
    }


    // outer brace of if (iscntrl(ch))
    }


    else if (!isascii(ch))
    {
    result = putchar(ch3);
    if (result == EOF)
    {
    break;
    }

    }


    else putchar(ch);


    // outer brace of while control
    }
    // outer brace of function
    }
    // gcc -o catv catv7.c >text22.txt 2>text23.txt
    // catv text42.txt >text43.txt

    I'm new to gcc. Does it have a debugger?

    I get no warnings now, and I think I should at least with int c declared and
    never referenced. How do I turn up the warnings?

    --
    c gordon liddy
     
    C. Gordon Liddy, Mar 31, 2008
    #8
  9. "santosh" <> wrote in message
    news:fso6fq$bf4$...
    >c gordon liddy wrote:
    >
    > <snip>
    >
    >> How would I populate a file containing non-ascii and ctrl chars for
    >> test purposes? (Does anyone have one?)

    >
    > The easiest way is to open the file in a hex editor and fill in the
    > character codes directly.

    Where does a person find such a thing?
    --
     
    C. Gordon Liddy, Mar 31, 2008
    #9
  10. "Richard Heathfield" <> wrote in message
    news:...
    > C. Gordon Liddy said:
    >
    > <snip>
    >
    >> Current output with catv is:
    >> the quick brown fox^J^@^A^B^C^D^E^F^G^H^I^J^K^L^M^N^O^P^Q^R^S^T^U^V^W^X^Y
    >>
    >> So after it reads and writes the control characters, it doesn't want to
    >> print anything more.

    >
    > It is very suggestive that your output stops at Ctrl-Z, which is used as
    > an
    > end-of-text-file marker by some systems. The fix is obvious - open the
    > file in binary mode:
    >
    > <snip>
    >
    >> #include <stdio.h>
    >>
    >> int main(int argc, char **argv)
    >> {
    >>
    >> FILE *fp;
    >> void filecopy(FILE *, FILE *);
    >>
    >> if (argc < 2) printf("die");
    >> else
    >> while (--argc > 0)
    >> if ((fp = fopen(*++argv, "r")) == NULL)

    >
    > Change "r" to "rb" and re-test.

    Thanks, Richard. My output is coming around.

    the quick brown
    fox^M^J^@^A^B^C^D^E^F^G^H^I^M^J^K^L^M^N^O^P^Q^R^S^T^U^V^W^X^Y^#^[^\^]^^^_
    !"#$%&'(jumps
    over^M^Jdefghijklmnopqrstuvwxyz{|}~^?MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMthe
    lazy dog^M^J

    Sometimes hitting the send button on a post is the exact stimulus one needs
    to realize what's in his blind spot: ctrl-z is eof for windows. rb instead
    of r works. I tried to do the same thing for that the original did for del:
    if (ch == '\177')
    {
    /* ch is DEL, we want "^?" */
    ch2 = '?';
    }
    else if(ch == 26)
    {
    /* we don't want ctrl-z coming out of here */
    ch2 = '#';
    }
    I'm puzzled that this didn't work.

    I've got some behavior for non-ascii characters. Again, I'll try to emulate
    what came off the bsd site:
    if (!isascii(ch)) {
    if (putchar('M') == EOF || putchar('-') == EOF)
    break;
    ch = toascii(ch);
    }

    Heck, I can just paste it in wholesale. Woo-hoo.

    --
     
    C. Gordon Liddy, Mar 31, 2008
    #10
  11. On Sun, 30 Mar 2008 02:22:25 -0700, "c gordon liddy" <>
    wrote:

    >What follows purports to be a soln for K&R 8-1 that prints bitshifted
    >control chars and non-ascii chars:
    >


    snip code copied from earlier message thread

    Why did you change the subject of the message and post the code again?
    See the comments in the putchar thread.

    >// gcc -o catv catv4.c
    >// catv text24.txt >text43.txt
    >
    >Abridged output from text43 is:
    >^JTarget: i386-pc-mingw32^J
    >
    >My guess is that J is what you get when you add octal 0100 to a carriage
    >return. Am I correct to think that the first 32 chars are control chars?


    On an ASCII system, \n (as your program sees it, not as it is stored
    in the file) is 0xoa which has a decimal representation of 10.

    >DEL appears to be 117 as well.


    You meant \177?

    >
    >How would I populate a file containing non-ascii and ctrl chars for test
    >purposes? (Does anyone have one?)


    Open a file for output and try
    int i;
    for (i = 0; i <= UCHAR_MAX; i++)
    fputc(i,fp);
    then close the file.


    Remove del for email
     
    Barry Schwarz, Mar 31, 2008
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. ernst
    Replies:
    3
    Views:
    366
    ernst
    Oct 28, 2003
  2. Ravi Ambros Wallau
    Replies:
    0
    Views:
    4,119
    Ravi Ambros Wallau
    Jun 1, 2005
  3. Peter Donis
    Replies:
    0
    Views:
    298
    Peter Donis
    Jan 11, 2008
  4. Steven D'Aprano
    Replies:
    1
    Views:
    368
    Patrick Maupin
    Apr 11, 2010
  5. Ravi Ambros Wallau
    Replies:
    0
    Views:
    333
    Ravi Ambros Wallau
    Jun 1, 2005
Loading...

Share This Page