program error

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Baloff

    program error

    Hello

    I wrote a code which is suppose to read a file which contains lines of
    double and prints it out.

    thanks for helping

    double.txt***** *************** *************** ****
    1.01
    2.0301
    3.0604
    4.10101
    5.15202

    in a stack.h I have
    //stack.h******** *************** *************** **
    #ifndef STACK_H
    #define STACK_H

    struct Stack
    {
    struct Link
    {
    void* data;
    Link* next;
    void initialize (void* dat, Link* nxt);
    }
    * head;
    void initialize ();
    void push (void* dat);
    void* peek ();
    void* pop ();
    void cleanup ();
    };
    #endif

    in my main.cpp
    string line;
    while(getline(i n, line)){
    textlines.push( reinterpret_cas t<void*>(&line) );
    }
    works ok but the following is not printing out the lines

    double* s;
    while(( s = static_cast<dou ble*>(textlines .pop() )) != 0) {
    cout << *s << endl;
    delete s;
    }
    [color=blue]
    > LocalWords: txt ifndef struct endif cpp ok[/color]
  • Kai-Uwe Bux

    #2
    Re: program error

    Baloff wrote:
    [color=blue]
    > Hello
    >
    > I wrote a code which is suppose to read a file which contains lines of
    > double and prints it out.
    >[/color]
    [snip][color=blue]
    > in a stack.h I have
    > //stack.h******** *************** *************** **
    > #ifndef STACK_H
    > #define STACK_H
    >
    > struct Stack
    > {
    > struct Link
    > {
    > void* data;
    > Link* next;
    > void initialize (void* dat, Link* nxt);
    > }
    > * head;
    > void initialize ();
    > void push (void* dat);
    > void* peek ();
    > void* pop ();
    > void cleanup ();
    > };
    > #endif[/color]

    Hm, you are using a stack, so maybe you want to revert the order in
    printing?

    All these void pointers are bad. You should use std::stack.
    [color=blue]
    >
    > in my main.cpp
    > string line;
    > while(getline(i n, line)){
    > textlines.push( reinterpret_cas t<void*>(&line) );
    > }
    > works ok ...[/color]

    Really? Now, I am pretty sure that this stores some *void items in your
    stack, all of which will happily point to the address of the string
    variable line which did not change!

    [color=blue]
    > ... but the following is not printing out the lines
    >
    > double* s;
    > while(( s = static_cast<dou ble*>(textlines .pop() )) != 0) {[/color]

    which kind of magic is this cast supposed to perform? textlines.pop() will
    return a *void pointing to &line. Now you are telling the compiler that it
    should not expect a string there but treat the bytes there as the
    representation of a double. [You might want to have a look into
    boost::lexical_ cast!]
    [color=blue]
    > cout << *s << endl;
    > delete s;[/color]

    Here, you are freeing memory that you nerver allocated!
    [color=blue]
    > }
    >[/color]

    Use the standard library:

    #include <stack>
    #include <iostream>
    #include <string>
    #include <fstream>

    int main ( void ) {
    std::stack< double > double_stack;
    {
    // read
    std::ifstream in_file ( "numbers.tx t" );
    double value;
    while ( in_file >> value ) {
    double_stack.pu sh( value );
    }
    }
    {
    // print
    while ( ! double_stack.em pty() ) {
    std::cout << double_stack.to p() << '\n';
    double_stack.po p();
    }
    }
    }


    Best

    Kai-Uwe Bux

    Comment

    • Rolf Magnus

      #3
      Re: program error

      Baloff wrote:
      [color=blue]
      > Hello
      >
      > I wrote a code which is suppose to read a file which contains lines of
      > double and prints it out.
      >
      > thanks for helping
      >
      > double.txt***** *************** *************** ****
      > 1.01
      > 2.0301
      > 3.0604
      > 4.10101
      > 5.15202
      >
      > in a stack.h I have
      > //stack.h******** *************** *************** **
      > #ifndef STACK_H
      > #define STACK_H
      >
      > struct Stack
      > {
      > struct Link
      > {
      > void* data;
      > Link* next;
      > void initialize (void* dat, Link* nxt);
      > }
      > * head;
      > void initialize ();
      > void push (void* dat);
      > void* peek ();
      > void* pop ();
      > void cleanup ();
      > };
      > #endif
      >
      > in my main.cpp
      > string line;[/color]

      You define one single string here.
      [color=blue]
      > while(getline(i n, line)){[/color]

      Now you go through the file, overwriting the string contents with the
      current line each time.
      [color=blue]
      > textlines.push( reinterpret_cas t<void*>(&line) );[/color]

      Then you put a pointer to the string object into your stack. Note that it's
      always the same string object and thus always the same pointer value. So at
      the end, you have a stack of pointers that point all to the same string,
      which contains the last line of your file, since that is what was last
      written to it.
      [color=blue]
      > }
      > works ok but the following is not printing out the lines
      >
      > double* s;
      > while(( s = static_cast<dou ble*>(textlines .pop() )) != 0) {[/color]

      You cannot just take a pointer to a string and treat it as if it were a
      pointer to double. This will not parse the string. It just interprets the
      bits that the string is composed of as double value. The result is of
      course garbage.
      [color=blue]
      > cout << *s << endl;
      > delete s;
      > }
      >[color=green]
      >> LocalWords: txt ifndef struct endif cpp ok[/color][/color]

      Wha?

      Comment

      • Baloff

        #4
        Re: program error

        I think I need to show the whole code, it is an exercise form Thinking
        In C++ by Bruce Eckel. page 255 (8)
        I need to make the Stack example in the book holds doubles, fill it
        with 25 double values and print them out.

        thanks

        //: C04:Stack.h**** *************** ***********
        // From Thinking in C++, 2nd Edition
        // Available at http://www.BruceEckel.com
        // (c) Bruce Eckel 2000
        // Copyright notice in Copyright.txt
        // Nested struct in linked list
        #ifndef STACK_H
        #define STACK_H

        struct Stack {
        struct Link {
        void* data;
        Link* next;
        void initialize(void * dat, Link* nxt);
        }* head;
        void initialize();
        void push(void* dat);
        void* peek();
        void* pop();
        void cleanup();
        };
        #endif // STACK_H ///:~

        //: C04:Stack.cpp {O}************ *************
        // From Thinking in C++, 2nd Edition
        // Available at http://www.BruceEckel.com
        // (c) Bruce Eckel 2000
        // Copyright notice in Copyright.txt
        // Linked list with nesting
        #include "Stack.h"
        #include "../require.h"
        using namespace std;

        void
        Stack::Link::in itialize(void* dat, Link* nxt) {
        data = dat;
        next = nxt;
        }

        void Stack::initiali ze() { head = 0; }

        void Stack::push(voi d* dat) {
        Link* newLink = new Link;
        newLink->initialize(dat , head);
        head = newLink;
        }

        void* Stack::peek() {
        require(head != 0, "Stack empty");
        return head->data;
        }

        void* Stack::pop() {
        if(head == 0) return 0;
        void* result = head->data;
        Link* oldHead = head;
        head = head->next;
        delete oldHead;
        return result;
        }

        void Stack::cleanup( ) {
        require(head == 0, "Stack not empty");
        } ///:~

        //: C04:StackTest.c pp************* ************
        // From Thinking in C++, 2nd Edition
        // Available at http://www.BruceEckel.com
        // (c) Bruce Eckel 2000
        // Copyright notice in Copyright.txt
        //{L} Stack
        //{T} StackTest.cpp
        // Test of nested linked list
        #include "Stack.h"
        #include "../require.h"
        #include <fstream>
        #include <iostream>
        #include <string>
        using namespace std;

        int main(int argc, char* argv[]) {
        requireArgs(arg c, 1); // File name is argument
        ifstream in(argv[1]);
        assure(in, argv[1]);
        Stack textlines;
        textlines.initi alize();
        string line;
        // Read file and store lines in the Stack:
        while(getline(i n, line))
        textlines.push( new string(line));
        // Pop the lines from the Stack and print them:
        string* s;
        while((s = (string*)textli nes.pop()) != 0) {
        cout << *s << endl;
        delete s;
        }
        textlines.clean up();
        } ///:~

        //: :require.h***** *************** **********
        // From Thinking in C++, 2nd Edition
        // Available at http://www.BruceEckel.com
        // (c) Bruce Eckel 2000
        // Copyright notice in Copyright.txt
        // Test for error conditions in programs
        // Local "using namespace std" for old compilers
        #ifndef REQUIRE_H
        #define REQUIRE_H
        #include <cstdio>
        #include <cstdlib>
        #include <fstream>
        #include <string>

        inline void require(bool requirement,
        const std::string& msg = "Requiremen t failed"){
        using namespace std;
        if (!requirement) {
        fputs(msg.c_str (), stderr);
        fputs("\n", stderr);
        exit(1);
        }
        }

        inline void requireArgs(int argc, int args,
        const std::string& msg =
        "Must use %d arguments") {
        using namespace std;
        if (argc != args + 1) {
        fprintf(stderr, msg.c_str(), args);
        fputs("\n", stderr);
        exit(1);
        }
        }

        inline void requireMinArgs( int argc, int minArgs,
        const std::string& msg =
        "Must use at least %d arguments") {
        using namespace std;
        if(argc < minArgs + 1) {
        fprintf(stderr, msg.c_str(), minArgs);
        fputs("\n", stderr);
        exit(1);
        }
        }

        inline void assure(std::ifs tream& in,
        const std::string& filename = "") {
        using namespace std;
        if(!in) {
        fprintf(stderr, "Could not open file %s\n",
        filename.c_str( ));
        exit(1);
        }
        }

        inline void assure(std::ofs tream& out,
        const std::string& filename = "") {
        using namespace std;
        if(!out) {
        fprintf(stderr, "Could not open file %s\n",
        filename.c_str( ));
        exit(1);
        }
        }
        #endif // REQUIRE_H ///:~
        [color=blue]
        > LocalWords: Eckel txt struct ifndef dat endif namespace std nxt newLink cpp
        > LocalWords: oldHead StackTest fstream iostream int argc argv requireArgs
        > LocalWords: ifstream textlines getline cstdio cstdlib inline bool const msg
        > LocalWords: args requireMinArgs minArgs[/color]

        Comment

        • Karl Heinz Buchegger

          #5
          Re: program error

          Baloff wrote:[color=blue]
          >
          > I think I need to show the whole code, it is an exercise form Thinking
          > In C++ by Bruce Eckel. page 255 (8)
          > I need to make the Stack example in the book holds doubles, fill it
          > with 25 double values and print them out.[/color]

          So then why don't you do exactly that?
          [color=blue]
          > int main(int argc, char* argv[]) {
          > requireArgs(arg c, 1); // File name is argument
          > ifstream in(argv[1]);
          > assure(in, argv[1]);
          > Stack textlines;
          > textlines.initi alize();
          > string line;
          > // Read file and store lines in the Stack:
          > while(getline(i n, line))
          > textlines.push( new string(line));[/color]

          You are not filling the stack with 'doubles'. You are
          filling it with std::string's.

          Either you *read* the file not with getline into a std::string
          but eg. into a double or you *convert* the string (which
          holds the textual representation of that number) into
          an actual number.
          [color=blue]
          > // Pop the lines from the Stack and print them:
          > string* s;
          > while((s = (string*)textli nes.pop()) != 0) {[/color]

          This will be wrong in any case. The stack holds pointers to
          double, not to std::string!


          --
          Karl Heinz Buchegger
          kbuchegg@gascad .at

          Comment

          • Baloff

            #6
            Re: program error

            Karl Heinz Buchegger <kbuchegg@gasca d.at> writes:
            [color=blue]
            > Baloff wrote:
            >[color=green]
            > >
            > > I think I need to show the whole code, it is an exercise form Thinking
            > > In C++ by Bruce Eckel. page 255 (8)
            > > I need to make the Stack example in the book holds doubles, fill it
            > > with 25 double values and print them out.[/color]
            >
            > So then why don't you do exactly that?[/color]
            to summarize the problem and reduce your time of reading a long post
            at first.
            [color=blue]
            >[color=green]
            > > int main(int argc, char* argv[]) {
            > > requireArgs(arg c, 1); // File name is argument
            > > ifstream in(argv[1]);
            > > assure(in, argv[1]);
            > > Stack textlines;
            > > textlines.initi alize();
            > > string line;
            > > // Read file and store lines in the Stack:
            > > while(getline(i n, line))
            > > textlines.push( new string(line));[/color]
            >
            > You are not filling the stack with 'doubles'. You are
            > filling it with std::string's.
            >
            > Either you *read* the file not with getline into a std::string
            > but eg. into a double[/color]

            how else would you read the file 'each line into a double'?
            [color=blue]
            > or you *convert* the string (which
            > holds the textual representation of that number) into
            > an actual number.
            >[/color]

            like this?
            string line;
            while(getline(i n, line)){
            textlines.push( new double( atof(line.c_str ()) ));
            }

            [color=blue][color=green]
            > > // Pop the lines from the Stack and print them:
            > > string* s;
            > > while((s = (string*)textli nes.pop()) != 0) {[/color]
            >
            > This will be wrong in any case. The stack holds pointers to
            > double, not to std::string!
            >
            >
            > --
            > Karl Heinz Buchegger
            > kbuchegg@gascad .at[/color]

            Comment

            • Karl Heinz Buchegger

              #7
              Re: program error

              Baloff wrote:[color=blue]
              >[color=green]
              > > Either you *read* the file not with getline into a std::string
              > > but eg. into a double[/color]
              >
              > how else would you read the file 'each line into a double'?[/color]

              come on.

              double value;

              while( in >> value ) {
              ..
              }

              [color=blue]
              >[color=green]
              > > or you *convert* the string (which
              > > holds the textual representation of that number) into
              > > an actual number.
              > >[/color]
              >
              > like this?
              > string line;
              > while(getline(i n, line)){
              > textlines.push( new double( atof(line.c_str ()) ));
              > }
              >[/color]

              Yep.
              But atof() isn't a very good function. There is no way to check
              if the string realy represents a valid number. Other methods
              would be to eg. use string stream.
              This topic has been beaten to death in this newsgroup. Search
              the archives at google.

              --
              Karl Heinz Buchegger
              kbuchegg@gascad .at

              Comment

              Working...