Quote:
> I'm new to the c language and I thought I could use the following simple shell
> program I wrote as a means to learn some basic functions in the c language
> dealing with the standard input/output library, fopen and such. The program
> prompts for a filename and then cuts a string of characters from a fixed length
> field file and (150 is the limit because the field consists of addresses in my
> mailbox and none of my friends have e-mail addresses over 100 characters
> in length). The program looks at each e-mail address writes out the length and
> then outputs it to a file if it is one of the longest in length. Not very real
> world in terms of usefulness, but it uses various aspects of the basics I'd
> like to learn in the language (I/O, redirects, array, counting, etc.) Of course
> the filename could just as easily be input as an argument too. Anyway if anyone
> could throw an idea out on how I would do something similar to this it would be
> appreciated. Any advice on some of the quicker ways to learn c would be
> appreciated too.
Dale,
it is not that easy to switch from shell programming to C
pogramming. C programming needs some syntactical additions
that do not appear in a shell program. For instance a program
must consist of functions, you cannot have code outside
a function block. There is one function that is called
at the program start, it is called main. Now one could go ahead
and translate your shell program into a C program, but it for
sure will take much more than this to learn the C language and
to learn programming in C. You at least should have one text
book to learn from, as you seem to be familiar with computers
and programming, I'ld suggest to go for "The C Programming
Language" by Kernighan and Ritchie (often referred to as K&R2).
Still, I'll try to give you some insights.
Quote:
> Example Shell Program
> ------------------------
#include <stdio.h>
#include <string.h>
#define MAXINPUT 256
#define MAXADDRESSLENGTH 150 /* from your requirements */
int main(void)
{
char address[MAXADDRESSLENGHT];
char inp[MAXINPUT];
FILE *input, *output;
Quote:
> length=1
> num=1
> echo "Input Filename: "
puts("Input Filename: ");
Quote:
> read inp
fgets(inp, sizeof inp, stdin);
if(inp[strlen(inp)-1] == '\n') {
inp[strlen(inp)-1] = '\0'; /* chop \n from read line */
Quote:
} else {
fputs("Input to long\n", stderr);
exit(1);
Quote:
}
/* now we need to open the file, so we can read it */
input = fopen(inp, "r");
if(!input) {
fputs("Can't open file\n", stderr);
exit(1);
Quote:
}
/* Now open the outfile */
strcat(inp, ".out"); /* create filename for output-file */
output = fopen(inp, "w");
if(!output) {
fputs("Can't open file\n", stderr);
exit(1);
Quote:
}
> #
> # Get total number of lines in the input file
> #
> tnum=`wc -l $inp`
/* to count the number of line, we have to read the whole file
and check for '\n'. That appears to be useless in many cases.
It is porbably better to simply read from the file until there
is nothing left to read. */
Quote:
> #
> # Chop out part of the file to run through the process
> #
> cat $inp | cut -c51-150 >> $inp.addr
/* This appears to be using a temporary file, where I don't
think you really need one. I really think that even in shell
programming you shouldn't be doing it that way. Also, you will
probably win the UUCA by Larry Wall (if I remember correctly)
for the above line, as cut can read from a file too. So there
is no need to call cat, but that all belongs to another
newsgroup. */
Quote:
> #
> # Pipe the stings through a loop and determine the string length
> #
> cat $inp.addr | while read address
while(fgets(address, sizeof address, input)) {
/* I stop at this point, because the rest of this program
is so confusing and disappears to be a usefull although
probably syntactically correct shell programm either.
You really want to everthink how to write this program
in both a shell and the C language.
*/
Quote:
> do
> #
> # Get string length here
> #
> cnum=`echo $address | wc -c`
> #
> # If the length is greater than the longest so far
> # append it to another file. Include total number
> # of records and the current record position in the file
> # as well as the length and string.
> #
> if [ $cnum -gt $length ]; then
> echo "$tnum $num $cnum $address" >> $inp.out
> echo "$tnum $num $cnum $address"
> #
> # Set the new length to the length of this record
> #
> length=$cnum
> #
> # If the length is the same as the longest append it to
> # the file also.
> #
> elif [ $cnum -eq $length ]; then
> echo "$tnum $num $cnum $address" >> $inp.out
> echo "$tnum $num $cnum $address"
> fi
The two cases you test for in this shell program could be
tested in one test. That would make disappear the redundant
code.
Quote:
> #
> # Increment the counter and output it to a counter file
> #
> num=`expr $num + 1`
> echo $num >> $inp.cnt
> done
}
}
--
"LISP is worth learning for the profound enlightenment experience
you will have when you finally get it; that experience will make you
a better programmer for the rest of your days." -- Eric S. Raymond