300 likes | 456 Views
CSE 20232 Lecture 9 – Files & More. DOS vs. UNIX files Ending lines with “<br>” vs. “<br>” Reading an entire line at a time getline() To skip white space or not cin >> ch; vs. ch = cin.get(); Command line args, again Examples & Demos. Rest of the week.
E N D
CSE 20232Lecture 9 – Files & More • DOS vs. UNIX files • Ending lines with “\r\n” vs. “\n” • Reading an entire line at a time • getline() • To skip white space or not • cin >> ch; vs. ch = cin.get(); • Command line args, again • Examples & Demos
Rest of the week • Introduction to functions & prototypes • Function parameters (formal and actual) • Value and reference parameters • Recursion • Template functions • Curses I/O • Text based windowing function library • Read: • Sections 6.10 - 6.17
DOS vs. UNIX Files • In DOS ASCII Text Files • All lines end withTWO characters • <return><newline> or “\r\n” • In UNIX ASCII Text Files • All lines end with ONE character • <newline> or ‘\n’ • Converting between two in UNIX/Linux • dos2unix – converts dos files to UNIX format • unix2dos – converts unix files to DOS format
DOS vs. UNIX Files • How will you know? • Open a DOS text file in some UNIX editors like “vi” and you will see a ‘^M’ character at the end of each line • These are the ‘\r’ or return characters • Open a UNIX text file using a DOS/Windows editor like “notepad” and the whole file appears to be on one line • This is because of the missing ‘\r’ characters
Reading an entire line • To read an entire line at once … • Declare a string variable string lineIn; • Use getline() to read the whole line from cin getline(cin, lineIn); • Or read the whole line from an istream • getline(inFile, lineIn);
Reading until a given char … • You can even read all of the line up to a specific character … • To read up to the next period • getline(cin, lineIn, ‘.’);
Getline() cautions • There is another version of getline() that is defined in the istream class and which uses char arrays as input buffers • Its arguments are • A char array, a limit number, a limit char (‘\n’ by default) • It is called like this • char buffer[100]; • cin.getline(buffer, 100); • infile.getline(buffer, 100, ‘.’)
Command line args, again … • The command line is broken up by white space • argc is the count of strings on the command line • argv is an indexed list (an array) of strings, from the command line, beginning with the name of the program
Sample Program - comline // comline.cpp – JHS -- 2006 // Usage: comline <arg> <arg> .... #include <iostream> #include <fstream> using namespace std; int main (int argc, char *argv[]) { cout << “Program run w/ following command line.\n"; for (int i=0; i<argc; i++) cout << ' ' << argv[i]; cout << endl; cout << "Command line arguments are ...\n"; cout << "argc = " << argc << endl; for (int i=0; i<argc; i++) cout << "argv[" << i << "] " << argv[i] << endl; return 0; }
Skipping White Space • By default, the input stream extractions (>>) are separated by white space, so this gets the next character that is NOT white space • cin >> ch; • The get() function gets the next character no matter what it is (whitespace or not) • ch = cin.get(); • Use what is appropriate • See cat.cpp vs. cat2.cpp for difference
Demo Programs • tocaps (using the (char) cast) • tocaps_oops (failing to use the (char) cast) • disks (C-style I/O) • more2 (uses getline) • cat vs. cat2 (ch=cin.get(); vs. cin >> ch;) • cat vs. ./cat (path issues, what gets run)
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); //cout << toupper(charIn); in “tocaps_oops.cpp” else // echo other character to screen cout << charIn; } infile.close(); return 0; }
Disks …Final example using C-style I/O • Program computes the volumes of a sequence of disks and outputs a summary report. • 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) • Examples: • 3 4.5 3.7 A • 5 1.0 1.0 G • Last line is the sentinel line • 0 0 0 q
Sample “diskdata.txt” File 3 4.5 1.0 A 2 3.5 1.55 F 1 0.3 2.0 R 5 6.1 3.6 V 0 0 0 q
Sample run of ./disks > ./disks diskdata.txt results.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 volume of all disks = 603.723 >
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; }
Program “cat.cpp” // cat.cpp – JHS 2006 // NOTE: This skips all white space & compresses text // Usage: cat <filename> #include <iostream> #include <fstream> using namespace std; int main (int argc, char *argv[]) { char charIn; ifstream infile; // do we have a correct command line with filename? if (argc != 2) { cout << "Usage: cat <filename>\n"; exit(1); }
Program “cat.cpp” // use filename to open file for input // argv[1] is the filename from the command line infile.open(argv[1]); if (infile.fail()) { cout << "File failed to open!" << endl; exit(2); } // get characters one at a time until end of file found infile >> charIn; // get 1st non whitespace character while (!infile.eof()) { cout << charIn; // echo character to screen infile >> charIn; // get next non whitespace character } infile.close(); return 0; }
Program “cat2.cpp” // cat2.cpp – JHS 2006 // NOTE: This reads and displays ALL text, even whitespace // Usage: cat2 <filename> #include <iostream> #include <fstream> using namespace std; int main (int argc, char *argv[]) { char charIn; ifstream infile; // do we have a correct command line with filename? if (argc != 2) { cout << "Usage: cat2 <filename>\n"; exit(1); }
Program “cat2.cpp” // use filename to open file for input // argv[1] is the filename from the command line infile.open(argv[1]); if (infile.fail()) { cout << "File failed to open!" << endl; exit(2); } // get characters one at a time until end of file found while ((charIn = infile.get()) != EOF) // get char & test { cout << charIn; // echo character to screen } infile.close(); return 0; }
Program – more2.cpp // more2.cpp – JHS 2006 // This program shows a file contents on the screen // (one page at a time), using getline() // Usage: more2 <filename> #include <iostream> #include <fstream> #include <string> using namespace std; int main (int argc, char *argv[]) { string lineIn; ifstream infile; int lines; // number of lines shown before pause bool quit; char resp;
Program – more2.cpp // do we have a correct command line with filename? if (argc != 2) { cout << "Usage: more2 <filename>\n"; exit(1); } // use filename to open file for input // argv[1] is the filename from the command line infile.open(argv[1]); if (infile.fail()) { cout << "File failed to open!" << endl; exit(2); } // get lines of text until end of file found lines = 0; quit = false; getline(infile,lineIn); // get first line
Program – more2.cpp while ((!infile.eof()) && (!quit)) { // NOTE: getline consumes the ‘\n’ at end of each line // but it is not made part of string. cout << lineIn << endl; // echo text line to screen lines++; if (lines > 24) { resp = cin.get(); if (resp == 'q') quit = true; // set flag so program quits else lines = 0; // reset line count } getline(infile,lineIn); // get next line of text } infile.close(); return 0; }
Path issues – what gets executed? • Your bash shell in Linux is the command interpreter • It’s environment can be displayed using • set and env • One of the variables is path or PATH • The order of directories in the path determines which version of a command or program gets run when you type its name • Typing a command this way ./prog tells the shell to look in the current directory for prog rather than searching the path
Path issues – what gets executed? • Example • There is a Linux command “disks” and we have a program called “disks” • Type disks and the Linux command is run > disks disks: you must be root to run this program • Type ./disks and our program is run > ./disks Usage: disks <input filename> <output filename> • Try cat & ./cat to see the difference between the Linux cat and ours.