A simple c program, reads an input file and just counts the characters. Will not work very well for unicode data but plain text ascii should be just fine.

So if one has a linux host and added the gcc package, open up a terminal, drop in the code, compile, and take a go or three at it.

A file for reading is kind of important too. Snag some content from anywhere, like maybe here: ENIAC wiki. Or use the dictionary file, most any unix host has a words file. It comes in handy for lots of stuff, like checking passwords for use of dictionary words, and other things. But first ... 

If direction is needed on compiling, see the detailed steps below.


  open a file for reading and count ascii characters
  usage: <foo> argv[1] required

  suggested usage:
    # create a file <foo> with some content and count the characters
    $ ./<prog> <foo>
    # same but sort the result numerically on 3rd column
    $ ./<prog> <foo> | sort -n -k 3
    # *some* unix flavours also allow:
    $ ./<prog> <foo> | sort -n +2
    # the -n +2 may work, may not. YMMV. not in linux.
#include <stdio.h>

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

  int iRtn =0;
  int iData[255];

  if ( argc != 2 ) /* argc should be 2 for correct execution */ {

    /* We print argv[0] assuming it is the program name */
    printf( "usage: %s <foo>\n", argv[0] );
    iRtn = 1;

  else {

    // We assume argv[1] is a filename to open
    FILE *file = fopen( argv[1], "r" );

    // fopen returns 0, the NULL pointer, on failure 
    if ( file == 0 ) {
      printf( "Could not open file %s.\n", argv[1] );
      iRtn = 2;
    else {

      int x,i;

      // initialize the counter buckets
      for ( i=0; i<255; i++) {
        iData[i] = 0;

      /* read one character at a time from file, stopping at EOF, which
         indicates the end of the file.  Note that the idiom of "assign
         to a variable, check the value" used below works because
         the assignment statement evaluates to the value assigned.

      while  ( ( x = fgetc( file ) ) != EOF ) {

        // could just dump it out here too
        //printf( "%c", x );

        // count up the input characters
        // if they are between ASCII 32 and 127 
        if ( x >= 32 )
          if (x < 128 )


      // tidy up
      fclose( file );

      // enable column headings here if you like
      //printf(" ASCII C  Count\n" );

      // dump the result for "printable" characters, no hi-ASCII codes
      for ( i=32; i<128; i++) {

        // print only the the not zero counts 
        if ( iData[i] != 0 ) {

          //printf("%6d %c %6d\n", i, i, iData[i] );
          // also try the first printf with sort -n -k 3 see what happens
          printf("%6d :%c %6d\n", i, i, iData[i] );

       } // endif iData[i] != 0
      } // endfor i=32; i<128; i++
    } // endif file == 0 
  } // endif argc != 2 

  // return code
  return iRtn;
//eof: fileread.c

Code is human readable instructions, at least for c programming, the code needs compilation to translate it to machine readable instructions, creating a runnable program. Or the code could also be compiled into a library file, shared by one or more programs.

And that's not too important right now, but first ...

Make a directory for c programs, keeping things tidy and somewhat organized  will allow for more easily finding your work later.

In a terminal window, create the source file and compile it with the cc compile program, and run it.

$ mkdir c
$ cd c
$ vi fileread.c
... tap the i key for insert mode
... paste in the code
... press <esc>
... type <colon>wq to save (write) and quit vi
$ ls -l
... fileread.c
$ cc fileread.c -o fileread
$ ./fileread  /usr/share/dict/words

To use the clipboard to copy and paste between the guest virtual machine and the host, the Guest Additions pieces have to be completed, and well as enabling the guest Shared Clipboard, on the guest Devices tab.

No comments:

Post a Comment