1
CS103Unit7Slides
FileI/O
MarkRedekopp
2
GettheFilesforToday• Gotoyourcs103/examplesdirectory
– $wget http://ee.usc.edu/~redekopp/cs103/redir_pipe.tar– $tarxvf redir_pipe.tar– $wget http://ee.usc.edu/~redekopp/cs103/cinfail.cpp– $wget http://ee.usc.edu/~redekopp/cs103/file_io_ex.tar– $tarxvf file_io_ex.tar
3
I/OStreams• I/Oisplacedintemporarybuffers/streamsbytheOS&C++libraries• cin pullsdatafromaninputstreamknownas'stdin'(standardinput)
– Itisusuallythestreamcomingfromthekeyboard
• cout putsdatainanoutputstreamknownas'stdout'(standardoutput)– Itisusuallydirectedtothemonitor
7 5 y ...
input stream [stdin] (user types all at once):
#include<iostream>using namespace std;int main(int argc, char *argv[]){int dummy, x; cin >> dummy >> x;
}
I t w a s t h e
output stream (stdout) in OS:
#include<iostream>
using namespace std;
int main(int argc, char *argv[]){cout << “It was the” << endl;cout << 4;
}
y ...stdin
4\n
It was the
6 1
stdout
4
I/OStreams• '>>'operatorusedtoreaddatafromaninputstream
– Alwaysstopsatwhitespace
• '<<'operatorusedtowritedatatoanoutputstream– 'endl'forcesaflush…FlushforcestheOStomovedatafromtheinternalOSstreamto
theactualoutputdevice(likethemonitor)
7 5 y ...
input stream (user types all at once):
#include<iostream>using namespace std;int main(int argc, char *argv[]){int dummy, x; cin >> dummy >> x;
}
I t w a s t h e
output stream in OS:
#include<iostream>
using namespace std;
int main(int argc, char *argv[]){cout << “It was the” << endl;cout << 4;
}
y ...input stream:4
output stream after flush:
4\n
It was the
6 1
5
FileI/OIntro
• Whatmethodsdoesauserhavetoprovideaprograminput:– cin– Commandline(argc,argv)
• Nowanewmethod:FileI/O(accessingdatainfiles)• Primarymethodforaprogramtoread/writefiles:
– Filestreams[Mainsubjectofourlecture]
• OS-basedtoolstoread/writefiledata– I/ORedirectionviatheOS(useof'<'and'>'atcommandline)– PipesviatheOS(useof|atcommandline)
6
Redirection&Pipes• TheOS(LinuxorWindowsorMac)providesthefollowing
abilitiesatthecommandline• '<'redirectcontentsofafileasinput(stdin)toprogram
– ./hailstats <input.txt– OSplacescontentsofinput.txtinto'stdin'inputstreamwhichbrokecan
accessvia'cin'
• '>'redirectprogramoutputtoafile– ./hailstats <input.txt>results.txt– OStakesoutputfrom'stdout'producedbycout andwritesthemintoa
newoutputfileontheharddrive:results.txt
• 'l'pipeoutputoffirstprogramtosecond– stdout offirstprogramisthenusedasstdin ofnextprogram
7
Redirection&PipeExamples• $./lab5_sol<input.txt
– Redirectscontentsofinput.txttostdin(i.e.cin)inlab5program
• Getthedemofiles:– Gotoyourcs103/examplesdirectory– $wget http://ee.usc.edu/~redekopp/cs103/redir_pipe.tar– $tarxvf redir_pipe.tar– $makerandgen– $makeaverage
• Runthemwithoutusingredirectionandpipes– $./randgen 2010
• Notice20valuesbetween1-10areoutputonstdout/cout
– $./average• NowtypeinalistofnumbersfollowedbytypingCtrl-D
0 10 10 100 500 200 220 20 301 80 180 25 251 180 50 30 602
input.txt
8
Redirection&PipeExamples
• OutputRedirection:>– $./randgen 2010>out.txt– Nowinspectout.txtcontents– Whatwouldhavedisplayedonthescreenisnowinout.txt
• Inputredirection:<– $./average<out.txt– Theoutputcapturedfromrandgen isnowusedasinputtoaverage
• Pipes:|– $./randgen 2010|./average– Theoutputofrandgen isfedasinputtoaverage
9
MOREABOUTSTREAMSOthercapabilitiesyoucanuseforstreams
10
Input&OutputStreams• Thereareothertypesofinputandoutputstreamsotherthancin andcout
• Filestreamsgivesthesamecapabilitiesofcin andcout exceptdataisread/writtenfrom/toafileontheharddrive– Everythingyoudowithcin usingthe'>>'operatoryoucannowusetoaccessdatafromafileratherthanthekeyboard
– Everythingyoudowithcout usingthe'<<'operatoryoucannowusetooutputdatatoafile
• Let'slearnmoreaboutstreams'>>'…we'llseeitinthecontextofcin andcout butrealizeitwillapplytootherstreamswe'lllearnaboutnext
11
Getline()andLinesofText• cin stopsreadingatwhitespace– Ifyouwanttoreadawholelineoftextusecin.getline()
• ItwillreadspacesandtabsbutSTOPat'\n'
– cin.getline(char*buffer,int max_chars)
• Readsmax_chars-1leavingspaceforthenullcharacter
#include <iostream> using namespace std;
int main () { char mytext[80];cout << "Enter your full name" << endl;cin.getline(mytext, 80);
int last=0;for(int i=0; i<80; i++){if(mytext[i] == ' '){
last = i;break;
} }cout << "Last name starts at index: ";cout << last << endl;return 0;}
12
SampleCode
• Getthesamplecode– $wget http://ee.usc.edu/~redekopp/cs103/cinfail.cpp
13
InputStreamErrorChecking• Wecancheckerrorswhencin
receivesunexpecteddatathatcan’tbeconvertedtothegiventype
• Usethefunctioncin.fail()whichreturnstrueifanythingwentwrongopeningorreadingdatainfromthefile(willcontinuetoreturntruefromthenonuntilyouperformcin.clear())
• Trythiscodeyourselfandseewhathappenswithandwithoutthecheckusingfail()
#include <iostream> using namespace std;
int main ()
{
int x;cout << "Enter an int: " << endl;cin >> x; // What if the user enters:
// “abc”
// Check if we successfully read an intif( cin.fail() ) {cout << "Error: I said enter an int!";cout << " Now I must exit!" << endl;return 1;
}
cout << "You did it! You entered an int";cout << " with value: " << x;
return 0;}
14
UnderstandingInputStreams
int x=0;
cout << “Enter X: “;
cin >> x;
int y = 0;
cout << “Enter Y: “;
cin >> y;
X =
cin =
X = cin =
X =
cin =
cin.fail() is false
Y = cin =
Y = cin =
Y = cin =
cin.fail() is false
● User enters value “512” at 1st prompt, enters “123” at 2nd prompt
0
0
512
5 1 2 \n
\n
0
0
123
\n 1 2 3 \n
\n
\n
15
UnderstandingInputStreams
int x=0;
cout << “Enter X: “;
cin >> x;
int y = 0;
cout << “Enter Y: “;
cin >> y;
X =
cin =
X = cin =
X =
cin =
cin.fail() is false
Y = cin =
Y = cin =
Y = cin =
● User enters value “23abc” at 1st prompt, 2nd prompt fails
0
0
23
2 3 a b
0
0
xx
c \n
a b c \n
a b c \n
a b c \n
a b c \n
cin.fail() is true
16
UnderstandingInputStreams
int x=0;
cout << “Enter X: “;
cin >> x;
int y = 0;
cout << “Enter Y: “;
cin >> y;
● User enters value “23 99” at 1st prompt, 2nd prompt skipped
X =
cin =
X = cin =
X =
cin =
cin.fail() is false
Y = cin =
Y = cin =
Y = cin =cin.fail() is false
0
0
23
2 3 9
0
0
99
9 \n
9 9 \n
9 9 \n
9 9 \n
\n
17
UnderstandingInputStreams
char x[80];
cout << “Enter X: “;
cin.getline(x, 80);
● User enters value “23 99” at 1st prompt, everything read as string
X =
cin =
X = cin =
X =
cin =
cin.fail() is false
NOTE: \n character is discarded!
23 99
2 3 9 9 \n
18
MoreonErrorChecking• Usethefail()functiontodetect
errorswhenattemptingtoreaddata
• Ifacalltofail()returnstruethensubsequentcallstofail()willcontinuetoreturntrueuntilyoucallclear()
• Useignore()tocleanoutanytextstillintheinputstream
• Trythiscodeyourselfandseewhathappenswithandwithoutthecheckusingfail()
#include <iostream> using namespace std;
int main ()
{
int x;cout << "Enter an int: " << endl;cin >> x; // What if the user enters:
// “abc”
// Check if we successfully read an intwhile( cin.fail() ) {cin.clear(); // turn off fail flagcin.ignore(256, '\n'); // clear inputscout << "I said enter an int: ";cin >> x;
}
cout << "You did it! You entered an int";cout << " with value: " << x;
return 1;}
19
FILESTREAMSHowyourprogramcandirectlyaccessdatainfiles
20
ComputerOrganization
• ProcessorcanonlytalkdirectlytoRAM– Itneeds“translation”toaccessdataontheharddriveorotherdisk
• AllcodeanddataresidesinRAM– Allvariablesaccessibleinyourprogram
• Howdoweaccessfiles– TheOSprovidesroutinestoperformthetranslation
Memory
…
…
…
Code
Stack (area for
data local to a function)
Globals
0
…
Heap
fffffffc
Data files:.ppt.txt
.docx
110010101001…
21
StartingFileI/O
• JustlikeMicrosoftWordoranyotherapplicationthatusesfilesyouhavetwooptions…– Readinfofromthefile(like'Open'command)
• Usean'ifstream' objecttoopenthefile• Readdatafromthefile• Closeitwhenyou'redone
– Writeinfotothefile(like'SaveAs'command)• Usean'ofstream' object• Writethedatatoafile• Closeitwhenyou'redone
22
ImportantFact
• Foryourprogramtooperateondatainafile…• …youmustreaditintoaCvariable• Everythingwewillseesubsequentlyissimplyhowtogetdataintoavariable– Afterthatwecanjustprocessitnormally– Ifwewanttoproduceanoutputfilewewilljustwritingthevariablevaluestothefileusingsomemoretechniques
– C/C++providesfunctionsthatdothereading/writingforyou
23
TwoKindsofFiles:BinaryandText
• Weconceiveoffilesas“streams”(lineararrays)ofdata• Filesarebrokenintotwotypesbasedonhowtheyrepresent
thegiveninformation:– Textfiles:FileisjustalargesequenceofASCIIcharacters(everypiece
ofdataisjustabyte)– Binaryfiles:Datainthefileisjustbitsthatcanberetrievedin
differentsizechunks(4-byteint,8-bytedouble,etc.)
• Example:Storethenumber172 inafile:– Text:Wouldstore3ASCIIchar’s‘1’,’7’,’2’(ASCII0x31,0x37,0x32)
requiring3bytes– Binary:If172wasina‘char’var.,wecouldstorea1-bytevalue
representing172inunsignedbinary(0xAC)orif172wasinan‘int’var.wecouldstore4-byteswithvalue0x000000AC
InthisclasswewillonlyfocusonTextfiles
24
TEXTFILEI/O
25
Activity
• Getthetestfiles– $wget http://ee.usc.edu/~redekopp/cs103/file_io_ex.tar– $tarxvf file_io_ex.tar
• sum_from_file_exercise
26
TextFileI/O• Useifstream object/variable
forreadingafile– Candoanything'cin'cando
• Useofstream object/variableforwritingafile– Candoanything'cout'cando
• Mustinclude<fstream>• Use'<<'and'>>'operatorson
thestreambutrealizeoperationsarehappeningondataformthefile
#include <iostream> #include <fstream> using namespace std;
int main ()
{
int x; double y;
ifstream ifile (“input.txt“);
if( ifile.fail() ){ // able to open file?cout << "Couldn't open file" << endl;return 1;
}
ifile >> x >> y; if ( ifile.fail() ){cout << "Didn't enter an int and double";return 1;
}
ofstream ofile(“output.txt“);
ofile << “Int from file is “ << x << endl;ofile << “Double from file is “ << y << endl;
ifile.close(); ofile.close();
return 0;}5 -3.5
input.txtInt from file is 5Double from file is -3.5
output.txt
27
GettingLinesofText• Usingthe>>operatortogetaninput
stringoftext(char*orchar[]variablepassedtocin)implicitlystopsatthefirstwhitespace
• Howcanwegetawholelineoftext(includingspaces)– cin.getline(char*buf,int bufsize);– ifile.getline(char*buf,int bufsize);– Readsmaxofbufsize-1characters
(includingnewline)• Thisprogramreadsallthelinesoftext
fromafile
#include <iostream> #include <fstream> using namespace std;
int main ()
{
char myline[100]; int i = 1;
ifstream ifile (“input.txt“);
if( ifile.fail() ){ // can't open?return 1;
}
ifile.getline(myline, 100);while ( ! ifile.fail()) {cout << i++ << “: “ << myline << endl;ifile.getline(myline, 100);}
ifile.close(); return 0;
}
The fox jumped over the log.\n
The bear ate some honey.\n
The CS student solved a hard problem.\n
1: The fox jumped over the log.
2: The bear ate some honey.
3: The CS student solved a hard problem.
input.txt
28
Activity
• reverse_it exercise• search_and_count exercise
29
FILELOCATION/POINTERS&INPUTOPERATORS
30
FileAccess• Yourifstream object(ifile)
implicitlykeepstrackofwhereyouareinthefile
• EOF (end-of-file)orothererrormeansnomoredatacanberead.Usethefail()functiontoensurethefileisokayforreading/writing
I t w a s t h e b e s t o f
...
fp
char c; ifile >> c;
a t f e r . T h e E n d ! EOF
fp
I t w a s t h e b e s t o f
fp
...
...
...
char c;while( ! ifile.fail() ) {ifile >> c;if(! ifile.fail()){ // process c }
}
Hard Drive
Hard Drive
31
>>Operator• Recallthatwithcin the>>operatorstops
gettingavaluewhenitencounterswhitespaceandalsoskipswhitespacetogettothenextvalue
– Sodoifstream objects
• Intheexampleonthisslide,thespaceswillNOTbereadin
– Theywillbeskippedbythe>>operator
• Togetrawdatafromthefile(includingwhitespaces)usetheget()function
I t 6 7 8
fp
char s[40]; ifile >> s;// returns “It” and stops at space
...
ifstream ifile("data.txt");
File text
I t 6 7 8
fp
...
File text
char x; ifile >> x;// skips space & gives x='6'
I t 6 7 8
fp
...
File text
32
>>Operator• Togetrawdatafromthefile(including
whitespaces)usetheifstream::get()function
– Returnsthecharacteratthe‘fp’andmoves‘fp’onbyone
• Toseewhatthenextcharacteriswithoutmovingthe‘fp’pointerontothenextcharacter,useifstream::peek()function
– Returnsthecharacteratthe‘fp’butdoesNOTmove‘fp’on
I 1 6 7 8
fp
char c = ifile.get(); // returns ‘I’C = ifile.get(); // returns ‘ ‘
...
ifstream ifile("data.txt");
File text
I 1 6 7 8 ...
char c; ifile >> c; // returns ‘I’Ifile >> c; // skips space and
// returns ‘1’
fp
File text
33
ChangingFilePointerLocation(ifstream)
• Ratherthanreadsequentiallyinafileweoftenneedtojumparoundtoparticularbytelocations
• ifstream.seekg()– Gotoaparticularbytelocation– Passanoffset relativefrom
currentpositionorabsolutebytefromstartorendoffile
• ifstream.tellg()– Returnthecurrentlocation’s
byte-offsetfromthebeginningofthefile
int main(int argc, char *argv[]){int size; char c;ifstream is(“stuff.txt”);
is.seekg(0,ios_base::end);size = is.tellg();cout << “File size (bytes)=“ << size << endl;
is.seekg(1, ios_base::beg);cout << “2nd byte in file is “;is >> c;cout << c << endl;is.seekg(-2, ios_base::cur);cout << “1st byte in file is “;is >> c;cout << c << endl;is.close();return 0;
}
2nd arg. to seekg()ios_base::beg = pos. from beginning of fileios_base::cur = pos. relative to current locationios_base::end = pos. relative from end of file
(i.e. 0 or negative number)
34
ChangingFilePointerLocation(ofstream)
• Wecanseekandtellinanofstream• ofstream.seekp()
– Gotoaparticularbytelocation– Passanoffsetrelativefromcurrentpositionorabsolutebytefromstartorend
offile• ofstream.tellp()
– Returnthecurrentlocation’sbyte-offsetfromthebeginningofthefile
2nd arg. to seekg()ios_base::beg = pos. from beginning of fileios_base::cur = pos. relative to current locationios_base::end = pos. relative from end of file
(i.e. 0 or negative number)
35
FILEI/OLABOVERVIEW
36
Lab7Overview
• Modifythewordscramblegamedoneinclasstoallowforawordbank(choiceofwordstouse)tobereadinfromafile
37
Lab7
• Openupthefileandcheckifitsucceeds
3 computertrojan hello
wordbank.txtIfstream object
38
Lab7
• Openupthefileandcheckifitsucceeds• Readthenumberofwordsexpected,checkifitsucceeds,andifso,allocatethewordBank arrayofpointers
3computertrojan hello
wordbank.txt
wordBank[0]wordBank[1]wordBank[2]
Ifstream object
39
Lab7
• Inaloopreadineachwordintoabufferandthenallocatesomememorytoholdthatwordandcopyittothatmemory
3 computertrojan hello
wordbank.txt
wordBank[0] 0x100wordBank[1]wordBank[2]
Ifstream object
computer
buf[41]
computer0x100
40
Lab7
• Inaloopreadineachwordintoabufferandthenallocatesomememorytoholdthatwordandcopyittothatmemory
3 computertrojan hello
wordbank.txt
wordBank[0] 0x100wordBank[1] 0x240wordBank[2]
Ifstream object
trojan
buf[41]
computer0x100
trojan0x240
41
Lab7
• Inaloopreadineachwordintoabufferandthenallocatesomememorytoholdthatwordandcopyittothatmemory
3 computertrojan hello
wordbank.txt
hello
wordBank[0] 0x100wordBank[1] 0x240wordBank[2] 0x320
buf[41]
computer
trojan
hello
0x100
0x240
0x320
Ifstream object
42
BINARYFILEI/OYouarenotresponsibleforthismaterial
43
BinaryFileI/O• read()– memberofifstream
– Passapointertowhereyouwantthedatareadfromthefiletobeplacedinmemory(e.g.&x ifxisasingleint ordata ifdataisanarray)…thispointershouldbecasttoachar*
– Pass#ofbytesyouwanttoread=number_of_elements *size_of_element
• write()– memberofofstream– Sameargument
schemeasread()
int main(int argc, char *argv[]){int x;double data[10];ifstream ifile;
ifile.open(“stuff.dat”,ios::binary);if ( ifile.fail()){cerr << “File doesn’t exist\n”;return 1;
}ifile.read(static_cast<char *>(&x), 1*sizeof(int));ifile.read(static_cast<char *>(data), 10*sizeof(double));
ifile.close();return 0;
}
44
stdin,stdout,stderr• MostOS’es mapconsoleI/O
(keyboardandmonitorI/O)to3predefinedFILEpointers:– stdin (inputfromkeyboard)=cin– stdout (outputtomonitor)=cout
• Normaloutput– stderr (outputtomonitor)=cerr
• Exception/errorinformation– Unix/Linuxcanallowyoutoredirect
stdout vs.stderr separately• >./prog >log_of_stdout.txt• >./prog >&log_of_stderr.txt
int main(int argc, char *argv[]){char first_char;char first_line[80];
// read char from keyboardcin << first_char;
// read entire line of text from// keyboardcin.getline(first_line, 80);
// echo line back to stdoutcout << first_line;
// output to stderrcerr << “I had an error.” << endl;
return 0;}
45
UNUSEDFALL2013
46
CSTYLEI/OYouarenotresponsibleforthismaterial
47
FILE*variables• Toaccessfiles,C(withthehelpoftheOS)
hasadatatypecalled‘FILE’whichtracksallinformationandisusedtoaccessasinglefilefromyourprogram
• YoudeclareapointertothisFILEtype(FILE*)
• You“open”afileforaccessusingfopen()– Passitafilenamestring(char*)andastring
indicatingreadvs.write,textvs.binary– ReturnsaninitializedfilepointerorNULLifthere
wasanerroropeningfile
• You“close”afilewhenfinishedwithfclose()– Passthefilepointer
• Bothofthesefunctionsaredefinedinstdio.h
int main(int argc, char *argv[]){char first_char;char first_line[80];FILE *fp;
fp = fopen(“stuff.txt”,”r”);if (fp == NULL){printf(“File doesn’t exist\n”);exit(1)
}// read first char. of filefirst_char = fgetc(fp);// read thru first ‘\n’ of filefgets(first_line, 80 ,fp);
fclose(fp);return 0;
}
Second arg. to fopen()“r” / “rb” = read mode, text/bin file“w” / “wb” = write mode, text/bin file“a” / “ab” = append to end of text/bin file“r+” / “r+b” = read/write text/bin fileothers…
48
FileAccess• ManyfileI/Ofunctions
– Textfileaccess:• fprintf(),fscanf()• fputc(),fgetc(),fputs(),fgets()
– Binaryfileaccess:• fread(),fwrite()
• Yourfilepointer(FILE*var)implicitlykeepstrackofwhereyouareinthefile
• EOF constantisreturnedwhenyouhittheendofthefileoryoucanusefeof()whichwillreturntrueorfalse.
I t w a s t h e b e s t o f
...
fp
c = fgetc(fp)
a t f e r . T h e E n d ! EOF
fp
I t w a s t h e b e s t o f
fp
...
...
...
while( ! feof(fp) )// okay to access next// byte of file
if((c = fgetc(fp) != EOF)// process c
49
TextFileInput• fgetc()
– GetasingleASCIIcharacter
• fgets()– Getalineoftextoracertainnumberofcharacters(uptoand
including‘\n’)– StopsatEOF…IfEOFisfirstcharreadthenthefunctionreturnsNULL– WillappendtheNULLcharattheendofthecharactersread
• fscanf()– ReadASCIIchar’sandconverttoanothervariabletype– Returnsnumberofsuccessfulitemsreador‘EOF’ifthatisthefirst
characterread
50
TextFileOutput• fputc()
– WriteasingleASCIIcharactertothefile
• fputs()– Writeatextstringtothefile
• fprintf()– Writetheresultingtextstringtothefile
51
BinaryFileI/O• fread()
– Passapointertowhereyouwantthedatareadfromthefiletobeplacedinmemory(e.g.&x ifxisanint ordata ifdataisanarray)
– Passthenumberof‘elements’toreadthenpassthesizeofeach‘element’
– #ofbytesread=number_of_elements*size_of_element
– Passthefilepointer
• fwrite– Sameargumentschemeasfread()
int main(int argc, char *argv[]){int x;double data[10];FILE *fp;
fp = fopen(“stuff.txt”,”r”);if (fp == NULL){printf(“File doesn’t exist\n”);exit(1)
}fread(&x, 1, sizeof(int), fp);fread(data, 10, sizeof(double),fp);
fclose(fp);return 0;
}
52
ChangingFilePointerLocation• Ratherthanread/writing
sequentiallyinafileweoftenneedtojumparoundtoparticularbytelocations
• fseek()– Gotoaparticularbytelocation– Canbespecifiedrelativefrom
currentpositionorabsolutebytefromstartorendoffile
• ftell()– Returnthecurrentlocation’sbyte-
offsetfromthebeginningofthefile
int main(int argc, char *argv[]){int size;FILE *fp;
fp = fopen(“stuff.txt”,”r”);if (fp == NULL){printf(“File doesn’t exist\n”);exit(1)
}fseek(fp,0,SEEK_END);size = ftell(fp);
printf(“File is %d bytes\n”, size);
fclose(fp);return 0;
}
Third arg. to fseek()SEEK_SET = pos. from beginning of fileSEEK_CUR = pos. relative to current locationSEEK_END = pos. relative from end of file
(i.e. negative number)