310 likes | 469 Views
CSE 20232 Lecture 8 – Loops, Files & More. Linux Piping and I/O redirection |, <, >, >> C style I/O Input: scanf(…), fscanf(…) Output: printf(…), fprintf(…) C files FILE, fopen(), fclose() Command line arguments argc & argv. Piping with “|†in Linux.
E N D
CSE 20232Lecture 8 – Loops, Files & More • Linux Piping and I/O redirection • |, <, >, >> • C style I/O • Input: scanf(…), fscanf(…) • Output: printf(…), fprintf(…) • C files • FILE, fopen(), fclose() • Command line arguments • argc & argv
Piping with “|” in Linux • The output of one command or program can be piped directly as input to another • Examples: • Count the number of .cpp files ls *.cpp | wc • Send a file of values into our avgN program cat valuesN.txt | avgN
Redirecting Input to come from a file using “<“ • A command or program that expects user input can be sent the values from a file • Note: User prompts still come out on screen, but the program will not wait for user input • Examples: • Run avgN with input coming from a file avgN < valuesN.txt
Redirecting Output to go to a file using “>“ • All program console outputs can be sent to a file instead • Notes: • User prompts will go to the file, but the program WILL still wait on any expected user inputs • “>” will create a new file for the output, but cannot append to or replace an existing file • Examples: • Capture directory listing in a file ls *.cpp > cpp_files.txt
Redirecting Output to be appended to a file using “>>“ • All program console outputs can be appended to an existing file instead • Notes: • User prompts will go to the file, but the program WILL still wait on any expected user inputs • “>>” will not create a new file for the output, but will append to an existing file • Examples: • Create a merger of two c++ code files cat pgm1.cpp > myCode.txt cat pgm2.cpp >> myCode.txt
C-style I/O • Input using scanf() • Controlled by a format string (conversion codes) • Uses addresses of variables and objects • Output using printf() • Controlled by a format string (conversion codes) • Uses sequence of variables and objects
The & operator • The & operator returns the address of a variable or object • This is also called a reference or pointer to the variable or object • Example: • int x = 5; • The value of x is 5 • The address of x is 4000 Memory ... 399940004001 ... x
C style input – scanf(…) • Scanf() is essentially doing the same task as cin >> • Format: scanf(<format string>,<variable references>); • Example: int x, y; // declare two integers scanf(“%d %d”, &x, &y); // read values x & y • The <format string> indicates the order and types of values being read • The <variable references> are the addresses of the variables (or objects) that will receive the values
Types of values:scanf () conversion codes • In the <format string>, the codes indicate what scanf() converts the characters in the input stream to … • %c a character • %d a decimal integer • %f a float • %lf a double • %s a string (C-style array of char)
C style output – printf(…) • printf() performs essentially the same task as cout << • Format: printf(<format string>, <variables>); • Example: int x, y; // declare two integers printf(“x=%d y=%d”, x, y); // output x & y • The <format string> indicates the format of the output, including types and context of values • The <variables> are the sources of the output values
Types of values:printf() conversion codes • In the <format string>, the codes indicate types and formats printf() converts the variable values to in the output stream … • %c a character • %d a decimal integer • %e a floating point number (scientific notation) • %f a floating point number (fixed notation) • %g %e or %f, whichever is shorter • %s a string
Order of listing matters • The conversion characters correspond to the variables or variable references in the order they are listed • Example: char name[32]; int age; printf(“Enter your first name and age\n”); scanf(“%s %d”, name, &age); printf(“Hello %s, you are %d\n”, name, age); • Note: name is the address of the first char in the character string, so we do not use &name with scanf()
Formatting output • Field width and number of digits right of the decimal point can be specified by placing a number (3) or a pair of numbers (5.2) in the conversion code • Example: • Output n in a field of 7 and x in fixed notation in a field of 10 with 3 digits right of the decimal printf(“n = %7d and x = %10.3f\n”, n, x); • Output: n = 345 and x = -123.453
Files in C • Rather than ifstreams and ofstreams we have one file type …FILE … defined in “stdio.h” • Declare a file pointer rather than a file stream #include <stdio.h> FILE *infile, *outfile; • Open input files using fopen() infile = fopen(”values.txt”, “r”); // reading outfile = fopen(“results.txt”, ”w”) // writing outfile = fopen(“results.txt”, ”a”) // appending
Is the file open? • After fopen() is called, the file pointer will have a value that is either … • a reference to the file stream or • a special value NULL, indicating failure to open • So, an open & test sequence looks like this FILE *infile; infile = fopen(“values.txt”,”r”); if (NULL == infile) { printf(“Input file failed to open.\n”); return 1; }
Input once the FILE is open • Use fscanf(…) to perform formatted reads from the file • Format: fscanf(<file ptr>, <format string>, <var refs>); • Example: fscanf(infile, “%d %f %f”, &n, &x, &y);
Output once the FILE is open • Use fprintf(…) to perform formatted writes to the file • Format: fprintf(<file ptr>, <format string>, <variables>); • Example: fprintf(outfile, “%d %f %f”, n, x, y);
Finishing up with the file • Close the file when done fclose(infile); fclose(outfile); • Note: the last bit of output on its way to an output file may not actually get flushed out of the stream into the file unless you close it before the program ends.
Command line arguments • Commands (and programs) can take the values following the command name as arguments • Examples: • more values.txt • ls *.cpp *.h • fstr2 hw2.doc • tocaps fstr2.cpp
Arguments to main() • Command line arguments are implemented in C/C++ using argc and argv as shown below • argc is the number of strings on the command line when the program execution begins • argv is an array (an indexed list) of those strings • The values of argc and argv are set by the operating system • Main now looks like this … int main (int argc, char *argv[]) { }
Examples • Assume the program words does something with the files listed after it on the command line • argc and argv have the values shown after this call • words test.txt hw1.cpp • argc=3 • argv[0] = “words” • argv[1] = “test.txt” • argv[2] = “hw1.cpp”
Sum …Sample use of argc and argv // file: sum.cpp – JHS06(computes sum of arguments) // usage: sum 3 5.5 -9.2 ... #include <iostream> #include <cstdlib> // for atof():string to float using namespace std; int main(int argc, char *argv[]) { double sum(0.0); for (int i=1; i<argc; i++) sum = sum + atof(argv[i]); cout << sum << endl; return 0; }
ToCaps …Another use of argc & argv // File: tocaps.cpp - JHS(9/14/2003) // Purpose: // Shows file contents on screen (IN ALL CAPS). // File specified by command line argument. // Discussion: // Demo of loops, file streams, & args to main. // Usage: tocaps <filename> #include <iostream> #include <fstream> #include <cctype using namespace std; int main (int argc, char *argv[]) { char charIn; ifstream infile;
ToCaps … Another use of argc & argv // do we have a correct command line with filename? if (argc != 2) { cout << "Usage: tocaps <filename>\n"; exit(1); } // use filename to open file for input // note: argv[0] is the command name “tocaps" // argv[1] is the filename from the command line infile.open(argv[1]); if (infile.fail()) { cout << "File failed to open!" << endl; exit(2); }
ToCaps … Another use of argc & argv // loop gets characters one at a time until // end of file is found while ((charIn = infile.get()) != EOF) { if (isalpha(charIn)) // echo upper case equivalent of letter cout << (char)toupper(charIn); else // echo other character to screen cout << charIn; } infile.close(); return 0; }
Disks …Final example using C-style I/O • A file contains lines of data. Each line describes a number and size of disks of a certain type. • Line Format: • number(int) diameter(float) thickness(float) type(char) • Exmples: • 3 4.5 3.7 A • 5 1.0 1.0 G • Last line is the sentinel line • 0 0 0 q
Disks.c /* ******************************** ** disks.c - JHS 06 (C-style I/O & computing disk volume) ******************************** */ #include <stdio.h> #define PI 3.14159 int main(int argc, char *argv[]) { FILE *infile, *outfile; int num; float radius, diameter, thickness, volume, total; char type; total = 0.0;
Disks.c if (argc != 3) { printf("Usage: disks <input file> <output file>\n"); return 1; } infile = fopen(argv[1],"r"); if (NULL == infile) { printf("Cannot open input file!\n"); return 2; } outfile = fopen(argv[2],"w"); if (NULL == outfile) { printf("Cannot create output file!\n"); return 3; }
Disks.c fscanf(infile,"%d %f %f %c", &num, &diameter, &thickness, &type); while (type != 'q') // while sentinel has not been read { radius = 0.5*diameter; volume = num*(PI*radius*radius*thickness); total = total + volume; /* show the user */ printf("%4d disks of type %c : volume = %10.3f\n", num, type, volume); /* output same information to disk */ fprintf(outfile, "%4d disks of type %c : volume = %10.3f\n", num, type, volume); /* read another line */ fscanf(infile,"%d %f %f %c", &num, &diameter, &thickness, &type); }
Disks.c printf("Total volume of all disks = %10.3f\n", total); fprintf(outfile,"Total volume of all disks = %10.3f\n", total); fclose(infile); fclose(outfile); return 0; }
User sees this … [jstewman]$ disks diskdata.txt Usage: disks <input filename> <output filename> [jstewman]$ disks diskdata.txt diskresults.txt 3 disks of type A : volume = 47.713 2 disks of type F : volume = 29.825 1 disks of type R : volume = 0.141 5 disks of type V : volume = 526.044 Total voume of all disks = 603.723 Same 5 lines of output also end up in file diskresults.txt