Help with simple file I/O :)

Discussion in 'C++' started by Kush, Nov 29, 2006.

  1. Kush

    Kush Guest

    Hello All,

    I am having problem writing some data to file and I do not understand
    my mistake / misconception.
    I am trying to write some simple text to file but the text is rather
    output to screen!

    Below is my entire code from my problem, but I just want to focus on
    the method "write_percentage_per_side_to_file(ofstream &os)". From my
    understanding I am passing an ofstream object which I declared in main(
    ) as "ofstream os = ("C:\\output.txt", ios::eek:ut);" into this method,
    and since I declared this as an output stream object, that using:

    os << "Text"

    Would write this to the filename I specified in my declaration of "os".

    Any help is appreciated!

    Cheers,

    Kush

    ----------------------------------------------------------------------------------------------------------------------------------------
    #include <iostream.h>
    #include <math.h>
    #include <fstream.h>

    //********************************************************Class
    definitions
    class coordinate
    {
    private:
    int x, y;
    public:
    void initialize(int a, int b);
    int provide_x_coordinate(void);
    int provide_y_coordinate(void);
    };

    class side
    {
    private:
    coordinate left_side, right_side;
    public:
    void initialize(int ax, int ay, int bx, int by);
    double length(void);
    };

    class property
    {
    private:
    side side1, side2, side3, side4;
    double perimeter(void);
    public:
    void initialize(void);
    void write_percentage_per_side_to_file(ofstream &os);
    };

    //********************************************************coordinate
    void coordinate::initialize(int a, int b)
    {
    x = a;
    y = b;
    }

    int coordinate::provide_x_coordinate(void)
    {
    return x;
    }

    int coordinate::provide_y_coordinate(void)
    {
    return y;
    }

    //********************************************************side
    void side::initialize(int ax, int ay, int bx, int by)
    {
    left_side.initialize(ax, ay);
    right_side.initialize(bx, by);
    }

    double side::length(void)
    {
    int left_x, left_y, right_x, right_y;

    left_x = left_side.provide_x_coordinate();
    left_y = left_side.provide_y_coordinate();
    right_x = right_side.provide_x_coordinate();
    right_y = right_side.provide_y_coordinate();

    return ( sqrt( ((right_x - left_x) * (right_x - left_x)) + ((right_y -
    left_y) * (right_y - left_y)) ) );
    }

    //********************************************************property
    void property::initialize(void)
    {
    side1.initialize(1, 6, 10, 10);
    side2.initialize(10, 10, 36, 4);
    side3.initialize(36, 4, 0, 0);
    side4.initialize(0, 0, 1, 6);
    }

    double property::perimeter(void)
    {
    return (side1.length() + side2.length() + side3.length() +
    side4.length() );
    }

    void property::write_percentage_per_side_to_file(ofstream &os)
    {
    os << "The percentage length of side1 relative to the perimeter is "
    << (side1.length() / perimeter() ) * 100 << endl
    << "The percentage length of side2 relative to the perimeter is " <<
    (side2.length() / perimeter() ) * 100 << endl
    << "The percentage length of side3 relative to the perimeter is " <<
    (side3.length() / perimeter() ) * 100 << endl
    << "The percentage length of side4 relative to the perimeter is " <<
    (side4.length() / perimeter() ) * 100 << endl;
    os.close();
    }

    //********************************************************main()

    void main(void)
    {
    property lot;
    lot.initialize();
    ofstream os = ("C:\\output.txt", ios::eek:ut);
    lot.write_percentage_per_side_to_file(os);
    }
    //********************************************************end of program
    Kush, Nov 29, 2006
    #1
    1. Advertising

  2. Kush

    Salt_Peter Guest

    Re: Help with simple file I/O :)

    Kush wrote:
    > Hello All,
    >
    > I am having problem writing some data to file and I do not understand
    > my mistake / misconception.
    > I am trying to write some simple text to file but the text is rather
    > output to screen!
    >
    > Below is my entire code from my problem, but I just want to focus on
    > the method "write_percentage_per_side_to_file(ofstream &os)". From my
    > understanding I am passing an ofstream object which I declared in main(
    > ) as "ofstream os = ("C:\\output.txt", ios::eek:ut);" into this method,
    > and since I declared this as an output stream object, that using:
    >
    > os << "Text"
    >
    > Would write this to the filename I specified in my declaration of "os".
    >
    > Any help is appreciated!
    >
    > Cheers,
    >
    > Kush
    >
    > ----------------------------------------------------------------------------------------------------------------------------------------
    > #include <iostream.h>
    > #include <math.h>
    > #include <fstream.h>


    #include <iostream>
    #include <cmath>
    #include <fstream>

    >
    > //********************************************************Class
    > definitions
    > class coordinate
    > {
    > private:
    > int x, y;
    > public:
    > void initialize(int a, int b);
    > int provide_x_coordinate(void);
    > int provide_y_coordinate(void);
    > };


    class coordinate
    {
    int x, y;
    public:
    coordinate(int a, int b);
    int getx() const;
    int gety() const;
    };

    >
    > class side
    > {
    > private:
    > coordinate left_side, right_side;
    > public:
    > void initialize(int ax, int ay, int bx, int by);
    > double length(void);
    > };


    class side
    {
    coordinate left_side, right_side;
    public:
    side(int ax, int ay, int bx, int by);
    side(const coordinate& ls, const coordiante& rs);
    double length() const;
    }

    >
    > class property
    > {
    > private:
    > side side1, side2, side3, side4;
    > double perimeter(void);
    > public:
    > void initialize(void);
    > void write_percentage_per_side_to_file(ofstream &os);
    > };
    >
    > //********************************************************coordinate
    > void coordinate::initialize(int a, int b)
    > {
    > x = a;
    > y = b;
    > }


    coordinate::coordinate(int a, int b) : x(a), y(b)
    {
    }

    >
    > int coordinate::provide_x_coordinate(void)
    > {
    > return x;
    > }


    int coordinate::getx() const
    {
    return x;
    }

    >
    > int coordinate::provide_y_coordinate(void)
    > {
    > return y;
    > }
    >
    > //********************************************************side
    > void side::initialize(int ax, int ay, int bx, int by)
    > {
    > left_side.initialize(ax, ay);
    > right_side.initialize(bx, by);
    > }


    again, use ctor. Why? Because there are more ctors than meet the eye:
    def ctor, parametized ctor, copy ctor and assignment operator - which
    itself is not a ctor. If you don't write the default ctors and op=, the
    compiler must generate them anyways. And the compiler will not default
    initialize members unless you tell it to.

    >
    > double side::length(void)
    > {
    > int left_x, left_y, right_x, right_y;
    >
    > left_x = left_side.provide_x_coordinate();
    > left_y = left_side.provide_y_coordinate();
    > right_x = right_side.provide_x_coordinate();
    > right_y = right_side.provide_y_coordinate();
    >
    > return ( sqrt( ((right_x - left_x) * (right_x - left_x)) + ((right_y -
    > left_y) * (right_y - left_y)) ) );
    > }
    >
    > //********************************************************property
    > void property::initialize(void)
    > {
    > side1.initialize(1, 6, 10, 10);
    > side2.initialize(10, 10, 36, 4);
    > side3.initialize(36, 4, 0, 0);
    > side4.initialize(0, 0, 1, 6);
    > }
    >
    > double property::perimeter(void)
    > {
    > return (side1.length() + side2.length() + side3.length() +
    > side4.length() );
    > }
    >
    > void property::write_percentage_per_side_to_file(ofstream &os)


    You should be passing the std::eek:fstream by std::eek:stream reference:
    void property::write_percentage_per_side_to_file(std::eek:stream &os)

    > {
    > os << "The percentage length of side1 relative to the perimeter is "
    > << (side1.length() / perimeter() ) * 100 << endl
    > << "The percentage length of side2 relative to the perimeter is " <<
    > (side2.length() / perimeter() ) * 100 << endl
    > << "The percentage length of side3 relative to the perimeter is " <<
    > (side3.length() / perimeter() ) * 100 << endl
    > << "The percentage length of side4 relative to the perimeter is " <<
    > (side4.length() / perimeter() ) * 100 << endl;
    > os.close();
    > }
    >
    > //********************************************************main()
    >
    > void main(void)
    > {
    > property lot;
    > lot.initialize();
    > ofstream os = ("C:\\output.txt", ios::eek:ut);


    Where is the error checking? How do you what, if anything, failed?

    std::eek:fstream ofs;
    ofs.open("C:\\output.txt");
    if(!ofs || !ofs.is_open() )
    {
    std::cerr << "error while opening file for output.\n";
    return -1;
    }

    > lot.write_percentage_per_side_to_file(os);
    > }
    > //********************************************************end of program
    Salt_Peter, Nov 29, 2006
    #2
    1. Advertising

  3. Re: Help with simple file I/O :)

    Salt_Peter wrote:

    > coordinate::coordinate(int a, int b) : x(a), y(b)


    What is this construct doing? I haven't seen a function defined like
    this before.

    Thanks,

    jw.
    James Willmott, Nov 29, 2006
    #3
  4. Kush

    Salt_Peter Guest

    Re: Help with simple file I/O :)

    James Willmott wrote:
    > Salt_Peter wrote:
    >
    > > coordinate::coordinate(int a, int b) : x(a), y(b)

    >
    > What is this construct doing? I haven't seen a function defined like
    > this before.
    >

    Coders who consider pointers to be friends have few acquaintances.
    > Thanks,
    >
    > jw.


    Its constructing an instance of coordinate using an "init list" with a
    and b as parameters to initialize the x and y members. Very fundamental
    in C++ and usefull since the ctor does not need to allocate the 2
    integers and *then* initialize their values. allocation +
    initialization is simultaneously carried out.

    Set a breakpoint in the ctors and watch the members x and y:

    #include <iostream>

    class coordinate
    {
    int x, y;
    public:
    // def ctor + init list
    coordinate() : x(0), y(0)
    {
    std::cout << "coordinate()\n";
    }
    // parametized ctor + init list
    coordinate(int a, int b) : x(a), y(b)
    {
    std::cout << "ctor coordinate(int,int)\n";
    }
    // copy ctor
    coordinate(const coordinate& copy)
    {
    std::cout << "copy ctor coordinate\n";
    x = copy.x;
    y = copy.y;
    }
    };

    int main()
    {
    coordinate coord; // def ctor invoked
    coordinate another(99,11); // parametized ctor invoked
    coordinate coord2(coord); // copy ctor invoked
    coordinate coord3 = another; // also a copy since
    }

    /* output:
    coordinate()
    ctor coordinate(int,int)
    copy ctor coordinate
    copy ctor coordinate
    */

    Can you see why this is usefull? Its absolutely impossible to create an
    instance of coordinate where x and y are left un-initialized by
    mistake. Say goodbye to bugs, thanks to the creator of the class.
    Next: assignment operator.

    By the way, other languages also have the compiler provide default
    ctors, they just don't tell you about it nor give you access to them.
    C++ takes a different view, ctors are one of its cornerstones.
    Salt_Peter, Nov 29, 2006
    #4
  5. Kush

    Kai-Uwe Bux Guest

    Re: Help with simple file I/O :)

    James Willmott wrote:

    > Salt_Peter wrote:
    >
    >> coordinate::coordinate(int a, int b) : x(a), y(b)


    You forgot to quote the empty body:
    {
    }
    >
    > What is this construct doing? I haven't seen a function defined like
    > this before.


    It's a constructor using an initializer list. Are you sure you never saw
    that? It should be explained in any book on C++.


    Best

    Kai-Uwe Bux
    Kai-Uwe Bux, Nov 29, 2006
    #5
  6. Re: Help with simple file I/O :)

    Kai-Uwe Bux wrote:
    > James Willmott wrote:
    >
    >
    >>Salt_Peter wrote:
    >>
    >>
    >>>coordinate::coordinate(int a, int b) : x(a), y(b)

    >
    >
    > You forgot to quote the empty body:
    > {
    > }
    >
    >>What is this construct doing? I haven't seen a function defined like
    >>this before.

    >
    >
    > It's a constructor using an initializer list. Are you sure you never saw
    > that? It should be explained in any book on C++.


    My C++ book doesn't even have namespaces in it.

    I've never heard of initialiser lists, but now that I know what they're
    called I can research them more myself. :)

    Thanks,
    jw.
    James Willmott, Nov 29, 2006
    #6
  7. Re: Help with simple file I/O :)

    Kai-Uwe Bux wrote:
    > James Willmott wrote:
    >
    >
    >>Salt_Peter wrote:
    >>
    >>
    >>coordinate::coordinate(int a, int b) : x(a), y(b)

    > {
    > }


    What's the benefit of doing that versus...

    coordinate::coordinate(int a, int b){
    x=a;
    y=b;
    }

    They seem to have the same end result at first glance?

    >>What is this construct doing? I haven't seen a function defined like
    >>this before.

    >
    >
    > It's a constructor using an initializer list. Are you sure you never saw
    > that? It should be explained in any book on C++.


    My C++ book doesn't even have namespaces in it. :)

    I've never heard of initialiser lists, but now that I know what they're
    called I can research them more myself.

    Thanks,
    jw.
    James Willmott, Nov 29, 2006
    #7
  8. Re: Help with simple file I/O :)

    James Willmott a écrit :

    > Kai-Uwe Bux wrote:
    > > James Willmott wrote:
    > >>Salt_Peter wrote:
    > >>coordinate::coordinate(int a, int b) : x(a), y(b)

    > > {
    > > }

    >
    > What's the benefit of doing that versus...
    >
    > coordinate::coordinate(int a, int b){
    > x=a;
    > y=b;
    > }
    >
    > They seem to have the same end result at first glance?


    But they don't work in the same way. The version with the initializer
    list constructs x and y with the corresponding values, while the second
    version construct them, then assign the value. While this is not very
    important for simple types, it can make a huge difference for more
    complex type where both the construction and the code for operator=()
    is slower. This is also the only way to construct sub objects that
    doesn't have a default constructor, or to assign references. For
    instance:

    class C
    {
    int& a;
    public:
    C(int val)
    {
    a = val;
    }
    };

    Doesn't work, because the reference requires to be initialized before
    you enter in the constructor body. You have to use a initializer list
    in this case.

    > >>What is this construct doing? I haven't seen a function defined like
    > >>this before.


    Of course you did: if class B inherit class A, how does B call the
    constructor of A?

    > My C++ book doesn't even have namespaces in it. :)


    I really suggest you to pick another book then :)

    Regards,

    -- Emmanuel Deloget, Artware
    Emmanuel Deloget, Nov 29, 2006
    #8
  9. Kush

    Earl Purple Guest

    Re: Help with simple file I/O :)

    James Willmott wrote:
    > Kai-Uwe Bux wrote:
    > > James Willmott wrote:
    > >
    > >
    > >>Salt_Peter wrote:
    > >>
    > >>
    > >>coordinate::coordinate(int a, int b) : x(a), y(b)

    > > {
    > > }

    >
    > What's the benefit of doing that versus...
    >
    > coordinate::coordinate(int a, int b){
    > x=a;
    > y=b;
    > }
    >
    > They seem to have the same end result at first glance?
    >

    May I suggest that you "FAQ off" .. well go and read this and the rest
    of the FAQ because you'll learn a lot from it.

    http://www.parashift.com/c -faq-lite/ctors.html#faq-10.6
    Earl Purple, Nov 29, 2006
    #9
  10. Re: Help with simple file I/O :)

    Emmanuel Deloget wrote:

    >>What's the benefit of doing that versus...
    >>
    >>coordinate::coordinate(int a, int b){
    >> x=a;
    >> y=b;
    >>}
    >>
    >>They seem to have the same end result at first glance?

    >
    >
    > But they don't work in the same way. The version with the initializer
    > list constructs x and y with the corresponding values, while the second
    > version construct them, then assign the value. While this is not very
    > important for simple types, it can make a huge difference for more
    > complex type where both the construction and the code for operator=()
    > is slower. This is also the only way to construct sub objects that
    > doesn't have a default constructor, or to assign references. For
    > instance:
    >
    > class C
    > {
    > int& a;
    > public:
    > C(int val)
    > {
    > a = val;
    > }
    > };
    >
    > Doesn't work, because the reference requires to be initialized before
    > you enter in the constructor body. You have to use a initializer list
    > in this case.


    class C
    {
    int& a;
    public:
    C(int val) : a(val)
    {
    }
    };

    Like this then?

    >>>>What is this construct doing? I haven't seen a function defined like
    >>>>this before.

    >
    >
    > Of course you did: if class B inherit class A, how does B call the
    > constructor of A?


    Ok, yes I did, but I didn't recognise it as such.

    >>My C++ book doesn't even have namespaces in it. :)

    >
    >
    > I really suggest you to pick another book then :)


    I intend to.

    Thanks,

    jw.
    James Willmott, Nov 29, 2006
    #10
  11. Re: Help with simple file I/O :)

    James Willmott wrote:
    > Kai-Uwe Bux wrote:
    >>>Salt_Peter wrote:
    >>>
    >>>
    >>>coordinate::coordinate(int a, int b) : x(a), y(b)

    >> {
    >> }

    >
    > What's the benefit of doing that versus...
    >
    > coordinate::coordinate(int a, int b){
    > x=a;
    > y=b;
    > }
    >
    > They seem to have the same end result at first glance?
    >

    No.
    You can always initialize a member, but if the member is const, then
    you can not assign a value to it once it has been initialized!

    try this code:
    #include <ostream>

    class Problem
    {
    public:
    Problem(int n);
    private:
    const int m_number;
    };

    Problem::problem(int n)
    {
    m_number = n; // Illegal because m_number is const!
    }

    int main()
    {
    Problem p1(1);
    }

    The point is the contructor will always initialize the members before
    entering the body of the constructor. By giving an initializer list
    you specify what values will be used to initialize the member. If no
    initialiser list is given default-initialisation occurs.

    Bo Møller
    Hobbyist

    --
    Bo Møller

    Hobby-Programmer
    =?ISO-8859-15?Q?Bo_M=F8ller?=, Nov 29, 2006
    #11
  12. Kush

    Earl Purple Guest

    Re: Help with simple file I/O :)

    A few points on the code. That I have not commented on any particular
    issue does not mean that the code is good at that point. It simply
    means I did not comment on it.

    Kush wrote:
    >>

    > ----------------------------------------------------------------------------------------------------------------------------------------
    > #include <iostream.h>
    > #include <math.h>
    > #include <fstream.h>


    Wrong headers. <iostream> <cmath> and <fstream> are the correct
    headers. You are a new C++ programmer or one from 10 years ago? Why are
    *new* C++ programmers being taught to include old headers?

    > //********************************************************Class
    > definitions
    > class coordinate
    > {
    > private:
    > int x, y;
    > public:

    void initialize(int a, int b);

    Bad as already pointed out. Do not have generally have public
    initialize() methods. You might have a private one which is called by a
    constructor.

    > int provide_x_coordinate(void);
    > int provide_y_coordinate(void);


    Bad style. Do not use (void) for functions with no parameters but
    instead use ()

    > class property
    > {
    > private:
    > side side1, side2, side3, side4;


    Almost certainly not good. Better to use a fixed length array. That
    also might not be the best design but it's pretty much likely to be
    better than four distinct members such that you cannot iterate through
    them.

    > double perimeter(void);
    > public:
    > void initialize(void);


    > void write_percentage_per_side_to_file(ofstream &os);


    Bad for three reasons. Firstly this method is not going to modify the
    class so it should be a const method. Secondly, it is bad to take
    ofstream & instead of the generic ostream & unless it is going to use
    features specific to ofstream. (And you'll need std:: to qualify
    ostream). The third bad thing is that the function calculates something
    and outputs it to a stream. Why can't you calculate something and
    return it?

    > };
    >
    > void property::write_percentage_per_side_to_file(ofstream &os)
    > {
    > os << "The percentage length of side1 relative to the perimeter is "
    > << (side1.length() / perimeter() ) * 100 << endl
    > << "The percentage length of side2 relative to the perimeter is " <<
    > (side2.length() / perimeter() ) * 100 << endl
    > << "The percentage length of side3 relative to the perimeter is " <<
    > (side3.length() / perimeter() ) * 100 << endl
    > << "The percentage length of side4 relative to the perimeter is " <<
    > (side4.length() / perimeter() ) * 100 << endl;
    > os.close();
    > }


    Bad to close the stream at the end. If you had used an array you could
    do something like:

    for ( int i=0; i<numSides; ++i )
    {
    os << "The percentage length of side" << i << " relative to the
    perimeter is "
    << side.length() / perimeter() ) * 100 << '\n';
    }
    os.flush(); // if you really want the flush

    The "function that calculates something" that I mentioned earlier would
    give you that percentage. Instead of putting that calculation in your
    loop here, you could call it each time. It could also be a public
    method so it could be called externally if someone using the class
    needs this percentage.

    > void main(void)


    main returns int. And don't use (void) of course as parameter list.

    > {
    > property lot;
    > lot.initialize();


    > ofstream os = ("C:\\output.txt", ios::eek:ut);


    Remove the = sign.

    If you used int main( int argc, char * argv[] ) then you could check if
    there is a runtime argument and use it as the output file. Much better
    than hard-coding it.
    Earl Purple, Nov 29, 2006
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    0
    Views:
    545
  2. Kevin Spencer

    Re: Simple Simple question!!!

    Kevin Spencer, Jun 25, 2004, in forum: ASP .Net
    Replies:
    0
    Views:
    647
    Kevin Spencer
    Jun 25, 2004
  3. Dave E
    Replies:
    7
    Views:
    734
    Josh Twist
    Jan 11, 2006
  4. Daniel Frey

    Simple Question - Simple Answer?

    Daniel Frey, Dec 28, 2004, in forum: XML
    Replies:
    4
    Views:
    825
    Daniel Frey
    Jan 12, 2005
  5. Replies:
    14
    Views:
    529
    Karl Heinz Buchegger
    Nov 2, 2005
Loading...

Share This Page