280 likes | 379 Views
CPS 393 Introduction to Unix and C. START OF WEEK 10 (C-4). Command line Processing. main is a function--so OS can pass arguments to it using Argument Vector, and Argument Count int main(int argc, char *argv[]) suppose -make executable cla from cla.c: gcc -o cla cla.c
E N D
CPS 393Introduction to Unix and C START OF WEEK 10 (C-4) Course material created by D. Woit
Command line Processing main is a function--so OS can pass arguments to it using Argument Vector, and Argument Count int main(int argc, char *argv[]) suppose -make executable cla from cla.c: gcc -o cla cla.c -and execute as: cla abc "de f" 74 -then inside cla.c: argc is 4 // # args + 1 (#elts in argv) argv[0] is "cla" // program name argv[1] is "abc" // argument 1 argv[2] is "de f" // argument 2 argv[3] is "74" // argument 3 9/21/2014 Course material created by D. Woit 2
Command line Processing • Program could print its COMMAND LINE ARGUMENTS as follows: • int main (int argc, char *argv[]) { • int i; • for (i=1; i<argc; i++) • printf("command line argument %d is: %s\n", i, argv[i]); • printf("Name of program is: %s\n", argv[0]); • exit(0); • } 9/21/2014 Course material created by D. Woit 3
/*Source: suma.c Purpose: to sum the integers supplied on the command line Input: any number of integers in command line Output: the sum of the inputted numbers */ #include <stdio.h> #include <stdlib.h> int main (int argc, char *argv[]) { int i, /*for loop index*/ sum=0; /*the sum of the arguments*/ for (i=1; i<argc; i++) { sum = sum + atoi(argv[i]); } printf("Sum of the %d integers is %d\n", argc-1, sum); exit(0); } HMWK: Fix suma.c so that it checks for good integer input 9/21/2014 Course material created by D. Woit 4
/*Source: cml2.c Purpose: print max of 2 int arguments */ #define GoodInput 0 #define BadInput 1 #include <stdio.h> int main (int argc, char *argv[]) { if (argc != 3 ) { fprintf(stderr, "Usage: %s int1 int2\n", argv[0]); exit(BadInput); } if (atoi (argv[1]) > atoi (argv[2]) ) fprintf(stdout, "%s\n", argv[1]); else fprintf(stdout, "%s\n", argv[2]); exit(GoodInput); } Note that functions strtof/strtod etc convert string to float/double etc 9/21/2014 Course material created by D. Woit 5
File I/O already used fprintf/fputs to print to FILE stdout, stderr fprintf(stderr, "bad input: %d\n", x); Others: fscanf (fp, str, length) fgetc (fp); fputc (ch, fp) fgets (str, length, fp); fputs (str, fp); 9/21/2014 Course material created by D. Woit 6
Open file named myfile for reading: FILE *fp; // FILE in stdio.h if ( (fp = fopen("myfile","r")) == NULL ) { fprintf(stderr,"fopen: Error opening file\n"); exit(1); } fscanf(fp, "%d", &i); Mode ---- r open text file for read w open text file for write a append to text file r+ open text file for r/w w+ create t.f. for r/w a+ append or create for r/w Note: w & w+: if file not exist, created if it exists, it is destroyed & new created File I/O 9/21/2014 Course material created by D. Woit 7
Closing a file fclose(fp); 0 if successful EOF if not (exit *should* close all files before pgm termination). fgetc(fp); returns: char read if succ (cast to int) EOF otherwise fputc(ch,fp); returns: char written if succ (cast to int) EOF otherwise 9/21/2014 Course material created by D. Woit 8
Example /*Source cio.c Purpose: write a string to file myfile */ #include <stdio.h> #include <stdlib.h> #define GOOD 0 #define BAD 1 int main(void) { char str[40] = "String to write onto disk"; FILE *fp; char ch, *p; if ((fp = fopen("myfile","w"))==NULL) { fprintf(stderr,"fopen: Cannot open file\n"); exit(BAD); } 9/21/2014 Course material created by D. Woit 9
p=str; while (*p) if (fputc(*p++,fp)==EOF) { fprintf(stderr,"fuptc: Error writing file\n"); fclose(fp); /*good form*/ exit(BAD); } fclose(fp); /*good form*/ exit(GOOD); } 9/21/2014 Course material created by D. Woit 10
/*Source: cio2.c Purpose: display contents of myfile on stdout */ #include <stdio.h> #include <stdlib.h> #define GOOD 0 #define BAD 1 int main(void) { FILE *fp; int ch; if ((fp=fopen("myfile", "r"))==NULL) { fprintf(stderr,"fopen: Cannot open file\n"); exit(BAD); } while (( ch = fgetc(fp)) != EOF) fputc(ch,stdout); fclose(fp); exit(GOOD); } Example 9/21/2014 Course material created by D. Woit 11
HMWK: Modify cio2.c to turn it into a simple version of unix utility "cat". If no cmd-line input, prints stdin on stdout. If cmd-line inputs (files), print each on stdout 9/21/2014 Course material created by D. Woit 12
/*Source: copy.c Purpose: copy file f1 to file f2 Usage: copy f1 f2 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #define GOOD 0 #define BAD 1 int main (int argc, char *argv[]) { FILE *f1, *f2; int ch; if (argc != 3) { fprintf(stderr, "Usage: %s <source> <destination>\n",argv[0]); exit(BAD); } 9/21/2014 Course material created by D. Woit 13
if ((f1=fopen(argv[1],"r"))==NULL) { fprintf(stderr, "Cannot open %s\n",argv[1]); exit(BAD); } if ((f2=fopen(argv[2],"w"))==NULL) { fprintf(stderr, "Cannot open %s\n",argv[2]); exit(BAD); } while ((ch=fgetc(f1)) != EOF) fputc(ch,f2); fclose(f1); fclose(f2); exit(GOOD); } 9/21/2014 Course material created by D. Woit 14
fgetc() returns EOF if 1) error in reading 2) hits EndOfFile can test for these separately feof(fp) non-0 if at EOF 0 otherwise ferror(fp) non-0 if error reading file 0 otherwise while (!feof(f1)) { ch=fgetc(f1); if (ferror(f1)) { fprintf(stderr, "Error reading ... exit(BAD); } if (!feof(f1)) fputc(ch,f2); if (ferror(f2)) { fprintf(stderr, "Error writing ... exit(BAD); } file i/o 9/21/2014 Course material created by D. Woit 15
fgets(str, length, fp); gets chars from FILE fp and stores them in array str, until 1. '\n' read (and transfered to s) 2. (length-1) chars have been read, or 3. EOF returns ptr to str if successful NULL ptr otws Note: -fp could be stdin -the file read pointer advanced "length-1" chars in the file. e.g., fgets(X,3,f1); fgets(Y,3,f1); for file with 12345 abcde will put "12" in X and "34" in Y fputs(str,fp) writes str to "file" ptd to by fp returns EOF if error; positive int otws 9/21/2014 Course material created by D. Woit 16
HMWK 1. Rewrite copy.c using fgets, fputs, feof and ferror assuming max line length in file is 128 chars. HMWK: 1. Write a program named prt.c that reads text from stdin until EOF and prints the number of lines and/or characters that were read in. The program takes one command line argument, which is l or c or b. If the argument is l, the program prints the number of lines, if c, the number of characters, and if b, it prints the number of both lines and chars. 9/21/2014 Course material created by D. Woit 17
HMWK 2. Re-write program prt.c above except this time, the program takes 2 arguments, the second argument being the name of a file from which to read the text. Perform *full* error checking. 3. Re-write the above prt.c so that any number of files are processed (number of chars/lines printed for EACH, in order processed.) 4. Use fscanf and fprintf to read a file with 2 columns of integers, such as: 2 4 7 9 10 6 and write the sum of each line to another file, e.g, 6 16 16 The file names are given on the command line 9/21/2014 Course material created by D. Woit 18
perror You could also use function perror (print error) instead of fprintf(stderr...); When any system or library function is called *and fails*, its return code (integer) is put in a system variable that perror can access. (clobbered with each failure). perror translates the integer to an (human understandable) phrase and prints on stderr, prefixed by its string argument e.g., FILE *fp; if ( (fp = fopen("myfile","r")) == NULL ) { perror("fopen"); exit(1); } 9/21/2014 Course material created by D. Woit 19
perror if "myfile" did not exist, stderr gets: fopen: No such file or directory (most of the built-in C functions use perror) FYI: All the error codes are defined in /usr/include/asm-generic/errno.h This C function perror in section 3 of man pages (man 3 perror) 9/21/2014 Course material created by D. Woit 20
Structures • Just as we can group items of same type into arrays, • We can group items of dissimilar types into: structures • struct s-name { • type item1; • type item2; • . . . • type itemN; • } ; 9/21/2014 Course material created by D. Woit 21
Structures • e.g., a struct to describe cars (in struct1.c) • struct car { • char make[40]; • char model[40]; • unsigned int year; • float price; • } ; • Then we can declare various variables of type struct car. • struct car woit, chan1, chan2; //3 cars 9/21/2014 Course material created by D. Woit 22
Assign woit's car: • strcpy(woit.make, "Ferrari"); • strcpy(woit.model, "F149"); • woit.year = 2012; • woit.price = 155000.00; • Read in chan1's car: • scanf("%s", chan1.make); //Porsche • gets(chan1.model); //Carrera • scanf("%u %f", &chan1.year, &chan1.price); //2013 440000 • Print woit's car's make: • printf("%s",woit.make); //prints Ferrari • printf("%c",woit.make[4]); //prints what? 9/21/2014 Course material created by D. Woit 23
Typedefs • give your own name to any data type • typedef short int Sint; • int i; • Sint j,k; 9/21/2014 Course material created by D. Woit 24
struct car { char make[40]; char model[40]; unsigned int year; float price; } chan1 ; //chan1 is a variable like woit and chan2 struct car woit; struct car chan2; typedef struct { char make[40]; char model[40]; unsigned int year; float price; } car; //car is a new datatype (such as Sint above) car woit; car chan1, chan2; Typedefs for structures 9/21/2014 Course material created by D. Woit 25
Arrays of structures • car (struct car) is now a datatype, therefore, we can create an array of cars • struct car chan[4]; /*if no typedef used*/ • or • car chan[4]; /*if typedef used*/ • How do we use arrays of structures? • chan's 0th car: chan[0].year = 1932; • chan's 3rd car: chan[3].price = 52399.99; • sizeof(struct car); /*no typedef*/ • or • sizeof(car); /*typedef*/ returns? 9/21/2014 Course material created by D. Woit 26
HMWK: • Write a program that reads an input file such as: • 1 5 • 2 -4 • -3 9 • 8 2 • Each line of the file contains a "complex number". • Assume at most MAX=100 numbers are given. • The program must create a structure for a complex number, and then store all the complex numbers in an array. (You must have an array of structures.) • Then your program should loop through the array from end to front, and print out the complex numbers in it. E.g., your output should • look like • 8 + 2i • -3 + 9i • 2 + -4i • 1 + 5i • on stdout. 9/21/2014 Course material created by D. Woit 27