Dynamic(arrays,(separate( compila1on,(and(file(IO - PLG

14
Dynamic arrays, separate compila1on, and file IO Supplementary notes CS246 Fall 2012 Mike Godfrey Dynamic arrays We now discuss “dynamic arrays” to give you an understanding of what goes on “under the hood” with vectors Dynamic arrays are a language feature of C++, meaning that the compiler has to provide special support for them The vector class is just a library class someone wrote for you; it is implemented in straighOorward C++ using dynamic arrays If you feel like you need a dynamic array in your program, you should almost certainly use an STL vector instead In facts there’s not much need to use any kind of arrays in C++ since we have vectors, plus other powerful container classes in the STL. std::array [Not on exam] The new C++ standard from 2011, known as "C++11", adds a new library class called std::array Basically, it's a nonZresizable sta1callyZallocated array, like a CZarray, but adds other vectorZlike API elements: at(), size(),… About as efficient as a CZarray, but with some added safety: at() method, disallows some kinds of unsafe accesses Why not use a vector instead? std::array is slightly more efficient If the array is declared on the stack, all of the element storage is also on the stack Even if a vector is declared on the stack, the actual storage for elements is a a dynamic array, which must come from the heap (Review) Arrays** All arrays are stored in con-guous memory i.e., element k is stored right ager element kZ1 This is also a requirement of vector and std::array, which is why they are both implemented using arrays This allows for fast random access of any element; it's address is a quick arithme1c computa1on If A is an array, then A[0] is stored at the address of A A[k] is stored at address A + k * element_size(A) **From this point on, "array" means C9style array as used in C++, not std::array

Transcript of Dynamic(arrays,(separate( compila1on,(and(file(IO - PLG

Dynamic(arrays,(separate(compila1on,(and(file(IO(

Supplementary(notes((

CS246(Fall(2012(Mike(Godfrey(

Dynamic(arrays(

•  We(now(discuss(“dynamic(arrays”(to(give(you(an(understanding(of(what(goes(on(“under(the(hood”(with(vectors(–  Dynamic(arrays(are(a(language'feature(of(C++,(meaning(that(the(

compiler(has(to(provide(special(support(for(them(–  The(vector(class(is(just(a(library(class(someone(wrote(for(you;(it(is(

implemented(in(straighOorward(C++(using(dynamic(arrays(

•  If(you(feel(like(you(need(a(dynamic(array(in(your(program,(you(should(almost(certainly(use(an(STL(vector instead(–  In(facts(there’s(not(much(need(to(use(any(kind(of(arrays(in(C++(since(

we(have(vectors,(plus(other(powerful(container(classes(in(the(STL.(

std::array [Not(on(exam]

•  The(new(C++(standard(from(2011,(known(as("C++11",(adds(a(new(library(class(called(std::array(–  Basically,(it's(a(nonZresizable(sta1callyZallocated(array,(like(a(CZarray,(

but(adds(other(vectorZlike(API(elements:(at(), size(),((…(–  About(as(efficient(as(a(CZarray,(but(with(some(added(safety:(at()

method,(disallows(some(kinds(of(unsafe(accesses(

•  Why(not(use(a(vector(instead?(–  std::array(is(slightly(more(efficient((–  If(the(array(is(declared(on(the(stack,(all(of(the(element(storage(is(also(

on(the(stack(–  Even(if(a(vector(is(declared(on(the(stack,(the(actual(storage(for(

elements(is(a(a(dynamic(array,(which(must(come(from(the(heap(

(Review)(Arrays**(

•  All(arrays(are(stored(in(con-guous(memory(i.e.,(element(k(is(stored(right(ager(element(kZ1(–  This(is(also(a(requirement(of(vector(and(std::array,(which(is(why(they(are(both(implemented(using(arrays(

•  This(allows(for(fast(random(access(of(any(element;(it's(address(is(a(quick(arithme1c(computa1on(–  If(A(is(an(array,(then((

•  A[0](is(stored(at(the(address(of(A •  A[k](is(stored(at(address(A(+(k(*(element_size(A)(

**From'this'point'on,'"array"'means'C9style'array'as'used'in'C++,'not'std::array'

(Review)(Arrays(

•  Can(think(of(A(as(just(being(a((const)(pointer(to(the(first(element(–  And(this(is(ogen(done(in(C/C++(programs(

e.g.,(CZstyle(strings(are(implemented(as(arrays(of(chars,(but(ogen(passed(to(procedures(as(a(char*

•  So(if(A(is(an(array(of(strings(or(Balloons,(we(can(think(of(A(as(being(a(pointer(to(a(string/Balloon –  As(long(as(we(remember(that(there(are(more(strings/Balloons(store(right(ager(it(in(memory(

–  But(A(must(always(point(to(that(storage,(can't(change(it(i.e.,(A(can(be(thought(of(as(being(of(type(const Balloon*

int main (int argc, char* argv[]) { const int N = 10; int A[N]; for (int i=0; i<N; i++) { A[i] = i*i; } int* p = A+6; // legal, means same as p = &A[6]; cout << "p points to " << *p << endl; p = A; // legal, means same as p = &A[0]; int* B = A; // legal, means same as B = &A[0]; // A = p; // illegal, as A is a const int* // Each of these is legal and prints same value for (int i=0; i<N; i++) { cout << "A[" << i << "] = " << A[i] << endl; cout << i << "[A] = " << i[A] << endl; cout << "B[" << i << "] = " << B[i] << endl; cout << "*(B+" << i << ") = " << *(B+i) << endl; cout << "*p = " << *p << endl; p++; // increment p to next element } }

C++(arrays(

1.  Sta1cally((•  Storage(is(allocated(on(the(stack((•  Array(bound(must(be(a(compileZ

1me(constant(•  Array(elements(are(store(in(

con1guous(memory!(

int main (…) { const int N = 5; int A[N]; // legal int m; cin << m; int B[m]; // illegal …

}

•  C++(arrays(can(be(declared(in(two(ways:(

Dynamic(arrays(

int main (…) { int N; cin >> N; int* A = new int[N]; string* B = myAlloc(N); for (int i=0; i<N; i++){ cin >> A[i] >> B[i]; } // … do more fun stuff delete [] A; delete [] B; }

2.  Dynamically((•  Declare(array(name(as(a(ptr(to(

element(type;(instan1ate(via(new •  Storage(is(allocated(on(the(heap(•  Array(bound(can(be(a(runZ1me(value(

(posi1ve(int)(•  Need(to(delete(when(done(

−  Don't(forget("[]"(

string* myAlloc (int n) { assert (n>0); return new string[n]; }

Dynamic(arrays(

•  Can't(return(an(array(from(a(procedure(–  But(arrays(are(almost(just(pointers((with(a(special(syntax(for(accessing(elements,(etc.)(

–  So(can(return(a(ptr(instead,(if(we(allocate(the(storage(on(the(heap(

Dynamic(arrays(

•  How(does("delete []A("(work?(–  The(system(needs(to(remember(the(extent(of(the(array:(i.e.,(the(#(of(elements(in(the(heapZchunk(that(were(allocated(for(the(dynamic(array(

–  The(array(extent(must(this(be(associated(somehow(with(the(block(of(storage(on(the(heap,(not(with(the(ptr((which(is(just(a(plain(old(ptr)((

(Q:(Why(not(store(the(extent(right(at(the(beginning(of(the(array?(

A:(That(would(break(normal(array(addressing(+(ptr(arithme1c(–  Common(approach(is(to(use,(eg,(4(bytes(before'the(array(storage(to(hold(

the(extent(–  So(this(means(that(the(following(works(fine(

string* myAlloc (int n) { assert (n>0); return new string[n]; } int main (int argc, char* argv[]) { string* A = myAlloc(10); string* B = myAlloc(20); // swap the pointers A and B string* temp = A; A = B; B = temp; // … and the deletes are no problemo, eh. delete []A; delete []B; }

Separate(compila1on(

•  Small(programs((<1000(LOC)(can(fit(into(one(file(easily(enough(1.  Edit(flurble.cc 2.  Compile:(g++ flurble.cc 3.  Run(a.out

•  But(for(large(programs((hundreds,(or(thousands(of(classes!),(it's(more(prac1cal(to(separate(out(pieces(of(your(code(into(dis1nct(compila-on'units'–  With(one(file,(you(have(to(recompile(everything(from(scratch(each(

1me(you(make(a(change(–  With(mul1ple(files,(you(have(to(recompile(only(the(bits(that(changed(

(plus(the(other(bits(that(depend(on(them)(–  For(big(systems,(this(is(a(huge(savings!((Even(with(separate(

compila1on,(building(very(large(industrial(systems(from(scratch(can(take(a(couple(of(days(

Separate(compila1on(

•  Our((fairly(standard)(approach(–  For(each(class(in(your(program,(call(it(Foo

•  Put(the(class(declara-on((interface)(into(a(file(named(Foo.h((including(a(guard:(#ifndef(__FOO_H__)(

•  Put(the(impls'of(Foo's(methods(into(a(file(named(Foo.cc •  Put(the(main(func1on(into(a(file(named(main.cc

–  Some(use(.cpp or(.C as(the(file(ending(

•  There(are(two(main(phases(to(building(a(system(–  Compile(each(of(the(compila1on(units((the(.cc files)(

g++ -c Foo.cc // produces a new file: Foo.o –  Link(the(object(files((.o files)(into(single(executable(

g++ -o myProgram *.o

// File: "Balloon.h" #ifndef __BALLOON_H__ #define __BALLOON_H__ #include <string> // library using namespace std; class Balloon { public: Balloon (string colour); void speak () const; private: string colour; }; #endif /* __BALLOON_H__ */

// File: "Balloon.cc" #include <iostream> #include <string> // <> => library #include "Balloon.h" // ""=>local file using namespace std; Balloon::Balloon (string colour) :

colour(colour) { } void Balloon::speak() const { cout << colour << " balloon" << endl; }

// File: "Child.h" #ifndef __CHILD_H__ #define __CHILD_H__ #include <string> #include "Balloon.h" using namespace std; class Child{ public: Child (string name, string bColour); virtual ~Child(); void speak() const; private: string name; Balloon* pb; }; #endif /* __CHILD_H__ */

// File: "Child.cc" #include <iostream> #include <string> #include "Child.h" using namespace std; Child::Child(string name, string bColour) : name(name), pb(new Balloon(bColour)) {} Child::~Child(){ delete pb; } void Child::speak() const { cout << "Child named " << name << " with a "; pb->speak(); }

// File: "main.cc" #include <iostream> #include <string> #include "Balloon.h" #include "Child.h" using namespace std; int main (int argc, char* argv[]) { Child ian ("Ian", "red"); Child trev ("Trevor", "green"); Child * ems = new Child("Emily", "yellow"); trev.speak(); ian.speak(); ems->speak(); }

Separate(compila1on(

•  Now(we(compile(each(.cc(file(g++ -c Foo.cc // produces Foo.o

•  We(don't(explicitly(compile(the(.h files,(or(the(library(files((e.g.,(string,(iostream)(directly;(they(get(included(by(the .cc files(that(need(to(see(them(

•  I(also(like(to(use(these(compiler(op1ons:(g++ -ansi –pedantic –Wall –c Foo.cc

g++ -c Foo.cc —(What(happens(

1.  First,(the(C/C++'preprocessor'runs,(performing(#include,(#define(and(checking(#ifdef(and(#ifndef –  This(transforms(the(exis1ng(source(code(to(new(source(code(–  Try(g++ -E Foo.c if(you(want(to(look(at(the(results(of(this(phase(for(fun(

2.  Then,(any(classes(defined(using(templates(are(created;(this(is(called(template'instan-a-on''e.g.,(vector<string>(is(created(from(generic(library(defini1on(vector<T> –  This(transforms(the(source(code(from(the(previous(step(to(an(some(internal(

representa1on((that(is(probably(not(easy(to(read,(depending(on(the(compiler)(

3.  Then,(the(results(of(the(above(are(transformed(into(an(object(file,(Foo.o –  The(whole(process(goes(something(like(this:(

Source'text'9>'tokens'9>'parse'tree'9>'[op-miza-on]'9>'object'code'–  You(will(learn(more(about(this(in(CS241;(it's(fascina1ng(stuff(

What(does(#include(mean?(

•  Each(.cc file(is((usually)(compiled(separately(–  It(has(to(be(able(to(see(a(declara1on(for(any(library(and(userZdefined(

type(/(class(that(it(uses,(so(it(must(include(the(appropriate(.h files(–  The((eventual)(.o file(leaves(an(empty("slot"(for(the(declared((but(

not(yet(defined)(types,(to(be(filled(in(when(all(of(the(.o(files(are(linked(together(during(the(final(stage(of(compila1on(

•  #include(is(simple(textual(inclusion!(–  The(whole(included(file(gets(sucked(up(into(the(current(file(before(

being(sent(to(the(compiler(–  Note(that(the(ifndef(guard(prevents(the(rest(of(the(file(from(being(

included(more(than(once(

What(to(#include

•  Each(.cc file(must(include(the(corresponding(.h(file,(using(quotes(–  Tho(there(is(usually(no(main.h(file(for(main.cc e.g.,(#include "Child.h" // in Child.cc

•  Each(.cc and(.h(file(must(include(all(of(the(library(en11es(that(it(references,(using(angle(brackets(e.g.,(#include <string>

•  Each(.cc and(.h file(must(include(the(.h(file(of(any(userZdefined(class(it(references,(using(quotes(e.g.,(#include "Ballon.h" // in Child.h, Child.cc, …

Balloon.h(

main.cc(Child.cc(Balloon.cc(

Child.h(

<string>(

C++(Std(Library(

<iostream>(

[All(five(source(files(above(include(these(library(files](

Who(includes(whom?(

#include

Compile(guard(ifndef

Problem:)Both(main.cc(and(Child.h(need(to(include Balloon.h,(and(main.cc(needs(to(include(Child.h

–  So(Balloon.h(will(be(included(twice(when(we(compile(main.cc –  Without(the(ifndef(guard,(the(compiler(will(complain(when(it(sees(

the(class(declara1on(for(Balloon(for(the(second(1me(

•  With(the(ifndef(guard,(the(first(1me(Balloon.h,(is(included,(the(variable(__BALLOON_H__(has(not(been(seen(before,(so(it(is(defined(–  The(second(1me(Balloon.h is(included,(the(variable(has(been(

defined(already,(so(the(class(declara1on(is(skipped(–  There(is(nothing(magical(about(the(name(__BALLOON_H__,(it's(just(

conven1on(

Next(step:(Linking(

•  Assume(each(foo.cc file(has(now(been(compiled(into(an(object(code((binary)(file(foo.o(–  Because(we've(included(the(.h files(for(each(method/type(we(need,(

the(compiler(has(basically(leg("slots"(open(for(each(.o(file(for(appropriately(named(en11es(to(be(filled(in(later(

–  Once(all(of(the(.o files(have(been(generated,(we(throw(them(into(one(big(box(called(a.out(and(hope(all(of(the(defini1ons(can(now(be(resolved( g++ *.o // creates executable a.out

–  So(Child.o(is(looking(for(the(Balloon(cxrs,(which(it(finds(in(Balloon.o,(and(main.o(is(looking(for(Child(cxr,(dxr,(and(Child::speak()

–  a.out(should(have(a(main(program(defined,(which(is(what(gets(executed(if(you(run(a.out(at(the(command(line(

Note(on(inclusion(

•  Note(that(technically,(main.cc(doesn't(have(to(include(Balloon.h,(string,(or(iostream,(as(it(includes(Child.h(which(already(includes(them(–  However,(it(is(a(bad(idea(to(rely(on(this;(it's(much(beter(for(each(file(

to(include(all(of((and(only)(the(files(that(it(uses(–  It(doesn't(cost(anything,(since(the(ifndef(guards(prevent(double(

copying(

•  At(the(same(1me,(do(not(get(into(the(habit(of(including(files(you(don't(use/need(–  It(can(cause(code(bloat(and(confusion(later(on(–  In(large(industrial(systems,(unnecessary(includes(can(greatly(slow(

down(system(builds(•  If(you(include(a(file(that(you(don't(need(to,(and(it(changes(a(lot,(you(get(recompiled(a(lot!(

Balloon.h(

main.cc(Child.cc(Balloon.cc(

Child.h(

<string>( C++(Std(Library(<iostream>(

[All(five(source(files(above(include(these(library(files](

Who(depends(on(whom?(

Balloon.o( Child.o( main.o(

a.out(

#include

g++ -c

g++ *.o

Compila1on(dependencies(mater(

•  Let's(suppose(you've(compiled(your(program(successfully(and(then(you(decide(to(make(changes(on(some(of(the(source(files(–  You(may(not(have(to(recompile(everything!(

•  If(file(A.cc(depends((transi1vely)(on(file(B.h(and(file(B.h(changes,(then(A.cc(needs(to(be(recompiled(–  And(then(the(executable(has(to(be(relinked(via(g++ *.o((

•  So(if(Balloon.h changes,(what(has(to(be(redone?(–  What(about(Balloon.cc?(

Compila1on(dependencies(mater(

•  Changing(a(major(design(decision(typically(means(changing(.h(files(–  And(this(usually(means(changing(all(of(the(files(that(include(the(

changed(.h(files(to(accommodate(the(new(design,(as(well(as(recompiling(them(

–  In(a(big(system,(changing(a(.h(file(ogen(is(disrup1ve(to(developers(

•  Fixing(a(bug(or(changing(an(implementa1on(strategy(ogen(involves(changing(only(.cc files,(which(means(less(rebuilding(

#include

•  If(you(use(quotes,(the(compiler(looks(in(the(current(directory: include "Balloon.h" include "gui/mainMenu.h"

•  If(you(use(angle(brackets,(it(looks(in(the(standard(library(loca1ons: include <vector> (

•  But(where(are(the(interface(files(for(standard(library(stored?(–  Well,(ogen(they're(in(a(subdirectory(of(/usr/include –  Unless(they(aren't(…(and(there(is(no(standard(way(of(asking(where(this(

loca1on(is(!(–  But(the(good(news(is(that(the(compiler(knows(where(to(find(them,(so(you(

don't(really(need(to(worry("(

–  If(you(want(to(know(what(the(full(API(for(vector(looks(like,(consult(the(web!(

And(how(are(the(implementa1ons((of(library(func1ons(found?(

•  Well,(for(separately(compiled(libraries((esp.(for(CZlanguage(libs),(once(again(the(compiler(magically(knows(where(to(find(them(and(how(to(link(them(to(your(program(–  You(might(look(in(/usr/lib,(but(that's(prety(advanced(stuff,(and(

different(compilers(may(do(things(differently(anyway(

•  For(C++(libraries(that(use(templates((vector,(string,(iostream,(etc.)(the(world(is(a(bit(different(…(((

And(how(are(the(implementa1ons((of(library(func1ons(found?(

•  For(various(technical(reasons,(classes(that(are(defined(using(C++(templates(must(be(fully(defined(inside(the(interface(file((i.e.,(there's(no(.h/.cc split(

•  So(if(you(include(vector,(string,(iostream,(etc.,(you(are(actually(including(quite(a(bit(of(source(code!((–  And(you(don't(know(what(vector,(etc.(themselves(might(include(

•  This(means(that(each(.cc(file(that(includes(vector(has(its(own(copy(of(the(source(code(for(vector(etc.(pulled(in(by(the(preprocessor(during(compila1on(–  When(you(link(the(.o(files(at(the(end,(the(compiler(is(clever(enough(to(

consolidate(duplicates(in(the(final(executable(

Automa1ng(builds(using(make

•  There(is(a(powerful((old)(Unix(command(line(tool(called(make(that(can(automate(the(build(recipes((–  make(is((fairly(smart(about(what(need(to(be(rebuilt(ager(changes(

occur(–  You(need(to(give(it(a(recipe(for(building(your(system(in(a(file(called(Makefile

–  We(will(cover(make(and(crea1ng(a(Makefile(later(

•  There(are(many(other,(newer(build(commandZline(tools(also,(such(as(ant,(maven,(SCons,(…(

•  If(you(use(an(IDE(like(Eclipse(or(VisualStudio,(it(will(also(automa1cally(track(what(needs(to(be(recompiled(ager(change(

FYI:(Building(Java(programs(

•  In(Java,(we(don't(separate(out(interface(from(implementa1on,(it(all(goes(into(one(big(.java(file(–  Usually,(we(put(one(major(class(in(each(.java file,(tho(some1mes(

we(bend(this(rule,(e.g.,(inner(classes(

•  There(is(no(preprocessor(or(template(instan1a1on(phase(–  No(#include,(no(#ifndef(guards,(no(#define(macros,(…(

•  Usually,(for(a(given(program(comprising(many(classes,(there(is(one(class(that(has(the("real"(main(program(in(it(–  But(any(class(can(have(its(own(main(program(too;(this(is(done(mainly(

to(allow(individual(classes(to(perform(tes1ng(

FYI:(Building(Java(programs(

•  A(Java(source(file,(call(it(Foo.java,(can(be(compiled(separately($ javac Foo.java –  …(but(this(will(automa1cally(trigger(the(compila1on((if(needed)(of(all(

other(classes(that(Foo(uses(or(depends(on(–  javac is(smart(about(not(recompiling(files(that(haven't(changed(

since(last(1me(

•  Separate(compila1on(produces(a(file(called(Foo.class –  If(Foo(has(a(main(func1on,(you(can(run(it(at(the(command(line:($ java Foo

•  You(can(also(package(up(a(set(of(class(files(into(a(single,(executable(jar(file(for(convenient(redistribu1on(

((Review)(Simple(I/O(

•  …(is(much(simpler(than(C((or(Java)(

•  #include<iostream> gets(you(three(useful(�streams�:((1.  cin (standard(input),(2.  cout (standard(output),(and((3.  cerr (output(stream(you(should(send(error(messages(to)(

•  Use(these(operators:(<< for(output(and(>>(for(input(–  They(have(been(overloaded(for(you(already(to(work(with(numbers,(chars,(and(strings(

–  You(can(overload(them(yourself(to(work(with(your(own(classes(

#include <iostream> #include <string> using namespace std; int main (int argc, char* argv[]){ cout « "Hello world" « endl; cout « "pi is approx. " « 22/double(7) « endl; string name; int age; cout « "What's you name and age? "; cin » name » age; if (age<0) { cerr « "Error, age must be non-negative.\n"; exit; } …

}

Output(formaxng(

•  There(are(many(output(formaxng(op1ons(you(can(set(too((e.g.,(field(width,(jus1fica1on,(...(you(can(read(up(on(this(

#include <iomanip> // need this! // ... for (...) { cout << left << setw(20) << prof.getName() << " " << right << setw(10) << prof.getSalary() << endl; }

(Review)(Input(white(space(

•  Note(that(cin » foo » bar;(grabs(the(next(two(tokens(in(the(input(stream,(skipping(all(intermediate(white(space.((

•  If(you(want(to(read(a(line(at(a(1me((with(white(space(intact),(do(this:((

string line; getline (cin, line);

–  You'll(have(to(parse(the(input(string(yourself(–  The(newline(char(is(removed(from(the(input(stream(but(NOT(stored(in(

the(variable(line –  getline(works(with(other(kinds(of(input(streams(too,(not(just(cin(

(Review)(Input(and(EOF(

•  To(check(for(EOF(gracefully,(see(if(cin.eof() or(cin.fail() returns(true:((–  eof() checks(for(only(EOF(–  fail() checks(for(EOF(plus(other(possible(problems.((

•  Both(eof()(and(fail()(can(be(used(with(other(input(streams,(not(just(cin.(

•  Note(that(eof()/fail()(don't(return(true(un1l(you've(actually(tried(to(go(one(step(too(far.((–  Therefore,(you(need(to(check(right(ager(an(atempted(read(but(before(

using(the(variable(you(tried(to(read(into.((

#include <iostream> using namespace std; int main (int argc, char* argv[]) { double sum = 0; int count = 0; while (true) { // awkward version double next; cin >> next; if (cin.fail()) { // or �if (!cin) {� break; // out of loop } sum += next; count++; } if (count > 0) { cout << "Avg is � << sum/count <<endl; } return 0; }

#include <iostream> using namespace std; int main (int argc, char* argv[]) { double sum = 0; int count = 0; double next; // "cin >> next" returns "cin" as a value, which in turn // returns "cin.fail()" when co-erced into a bool while (cin >> next) { sum += next; count++; } if (count > 0) { cout << "Avg of " << count << " numbers is � << sum/count << endl; } return 0; }

File(I/O(

•  There(are(library(classes(ifstream(and(ofstream(that(you(can(instan1ate(to(get(easy(fileZbased(IO(–  Need(this:(#include <fstream>

•  Can't(use(filename(directly(in(IO(stmt;(instead,(must(create(a(stream(object(and(associate(it(with(the(file(name((–  Nit:(Stream(cxrs(expects(file(name(to(be(a(char*,(not(a(string –  Need(to(check(that(the(stream(crea1on(was(successful(right(away(–  If(stream(crea1on(fails,((e.g.,(input(file(not(found,(don't(have(correct(

permission(to(write),(then(myin.fail()(will(return(true

•  Once(created,(we(can(use(<< or(>>(on(the(stream(object,(just(like(cin(and(cout

#include <iostream> #include <fstream> using namespace std; int main (int argc, char* argv[]) { if (argc <= 1 ) { cerr << "Error, must provide input file name.\n�; exit (1); } ifstream is_rawGrades (argv[1]); // argv[1] is a char* if (!is_rawGrades) { cerr << "Can't open input file " << argv[1] << endl; exit (1); } ofstream os_pass ("passes"); // explicit string value OK ofstream os_fail ("failures"); // Should also check os_pass and os_fail are valid …

int grade; string name; while (is_rawGrades >> grade >> name) { if (grade >= 50 ) { os_pass << grade << " " << name << endl; } else { os_fail << grade << " " << name << endl; } } is_rawGrades.close(); os_pass.close(); os_fail.close(); }

#include <string> #include <fstream> #include <iostream> using namespace std; int main (int argc, char* argv[]) { // This works: "input.txt" can be considered to // be a char* ifstream myInputFile ("input.txt"); // Won't work: inFileName is a string, not a char* string inFileName = "input.txt"; ifstream myOtherInputFile (inFileName); // error // This works: string is coerced into a char* ifstream myLastInputFile (inFileName.c_str()); … }

Opening(and(closing(file(IO(streams(

•  Can(either:((–  Connect(stream(to(a(file(name(in(the(cxr(call,(or((

ifstream myin ("input.txt"); –  Create(stream(on(its(own(+(connect(to(a(file(later(via(open

ofstream myout; myout.open("output.txt");

(•  Either(way,(we(need(to(close(all(of(our(streams(when(we(are(done(– We(can(open(it(up(again(connected(to(a(different(filename((

myout.close(); myout.open("output2.txt");

#include <iostream> #include <fstream> #include <string> using namespace std; int main (int argc, char* argv[]) { ifstream myin1; myin1.open("in1.txt"); ifstream myin2 ("in2.txt"); if (!myin1 || !myin2) { cerr << "Couldn't open an input file" << endl; exit (1); } ofstream myout; myout.open ("out1.txt"); if (!myout) { cerr << "Couldn't open output file" << endl; exit (1); }

string s; myin1 >> s; myout << s << " into file 1" << endl; myout.close(); myout.open("out2.txt"); if (!myout) { cerr << "Couldn't open myout " << endl; exit (1); } myout << s << " "; myin2 >> s; myout << s << " into file 2" << endl; myout.close(); myin1.close(); myin2.close(); }

What,(exactly,(are(cin,(cout,(cerr?((

•  cin,(cout,(and(cerr(are(just(plain(old(global(variables(that(are(defined(by(the(C++(Standard(Library,(and(are(available(to(any(C++(program(that(includes(iostream(–  cin(is(just(an(instance(of(the(C++(Standard(Library(class(istream –  cout,(cerr(are(instances(of(ostream

•  If(you(want(to(be(able(to(read/write(either(to(a(file(or'one(of(the(standard(input/output(streams,(then(you(can(use(the(library(types(istream(and(ostream –  ostream(is(a(more'general'class'than(ofstream(i.e.,(any(instance(of(ofstream(can(be(treated(as(if(it(were(an(instance(of(ostream(([An(analogous(situa1on(holds(for(ifstream/istream](

// Recall this example from slides on operator overloading #include <iostream> #include <fstream> #include <string> using namespace std; class Greeter { public : Greeter (string name, ostream & myout); void speak() const; private : string name; ostream& myout; // Was ofstream last time }; Greeter::Greeter (string name, ostream &myout) : name(name), myout(myout){} void Greeter::speak() const { myout << "Bienvenue a Mart-du-Mur!" << endl; myout << "Je m'appelle " << name << endl; }

int main (int argc, char* argv[]) { if (argc == 1) { cerr << "Usage: " << argv[0] << " outputFilename\n"; exit (1); } ofstream myoutfile (argv[1]()); if (!myout) { cerr << "Error, couldn't open output file " << argv[1] << endl; exit(1); } Greeter frank ("Frank", myoutfile); frank.speak(); Greeter alice ("Alice", cout); alice.speak(); myout.close(); }

Inheritance(and(polymorphism(

•  Note(that(cout((and(cerr)(are(instances(of(ostream(,(whereas(myoutfile(is(an(instance(of(ofstream((–  This(is(allowed(because(the(class((ofstream(inherits(from(the(class(ostream –  [Also,(ifstream(inherits(from(istream]((

•  If(A(and(B(are(classes(where(B(inherits(from(A,(then(any(instance(of(B(may(be(used(where(the(assumed(type(is(A(–  This(is(called(polymorphism'–  So(we(can(pass(in(myoutfile(which(is(an(instance(of(ofstream(to(a(

parameter(whose(type(is(the(more(general(ostream –  And(we(can(assign(the(reference(instance(variable(myout(of(type(ostream(to(

refer(to(an(object(of(type(ofstream((–  There(is(some(subtlety(here(about(how(polymorphism(works(with(objects(vs.(

references(vs.(ptrs(which(we(will(explore(in(the(next(sec1on;(usually,(we(use(ptrs!(

C++(I/O(libraries(

[Diagram(from(http://www.cplusplus.com/reference/iostream/](

File)to)be)included) Class) Object)

Arrow)between)classes)means)"is)inherited)by")("is)a)more)general)kind)of)en?ty)than"))

Dynamic(arrays,(separate(compila1on,(and(file(IO(

Supplementary(notes((

CS246(Fall(2012(Mike(Godfrey(