Problem with Accessors

Discussion in 'C++' started by Jordan Tiona, Jan 13, 2006.

  1. Jordan Tiona

    Jordan Tiona Guest

    Here is my code.

    main.cpp:

    #include "cddb.h"

    CDData* head;
    CDData* curData;

    int main(){

    head = new CDData();
    curData = head;

    EnterInfo();
    Print();
    return 0;
    }

    void EnterInfo(){
    CDData* temp;
    char* input = new char();
    int ipInt;

    system("cls");

    temp = new CDData();
    curData->SetNext(temp);
    curData = temp;

    cout << "Please enter information about your new CD.\n";
    cout << "\nAlbum name: ";
    cin.getline(input, 25);
    curData->SetAlbumName(input);
    cout << "\nArtist name: ";
    cin.getline(input, 25);
    curData->SetArtistName(input);
    cout << "\nYear Released: ";
    cin >> ipInt;
    curData->SetYear(ipInt);
    }

    void Print(){
    int i = 1;
    curData = head;

    while(true){
    curData = curData->GetNext();
    if(curData = NULL)
    break;

    cout << "CD #" << i << endl;
    cout << "Album Name: " << curData->GetAlbumName() << endl;
    cout << "Artist Name: " << curData->GetArtistName() << endl;
    cout << "Year Released: " << curData->GetYear() << endl;
    cout << "-------------------------------------------\n\n";

    i++;
    }
    }

    cddb.h:

    #include <iostream>
    #include <string>
    using namespace std;

    void EnterInfo();
    void Save();
    void Load();
    void Print();

    class CDData {
    private:
    CDData *next; //For linked list
    char* albumName;
    char* artistName;
    int year;
    public:
    //Constructor/Destructor
    CDData(){ this->SetNext(NULL);}
    ~CDData(){}
    //Accessors
    char* GetAlbumName(){return this->albumName;}
    char* GetArtistName(){return this->artistName;}
    int GetYear(){return year;}
    CDData* GetNext(){return next;}

    void SetAlbumName(char* newName){albumName = newName;}
    void SetArtistName(char* newName){artistName = newName;}
    void SetYear(int newYear){year = newYear;}
    void SetNext(CDData* newNext){next = newNext;}
    };

    I'm getting an access violation error during runtime at the print function,
    when I'm trying to use the GetXXX accessors.

    Unhandled exception at 0x0041fc46 in CDDataBase.exe: 0xC0000005: Access
    violation reading location 0x00000004.

    What am I doing wrong?
     
    Jordan Tiona, Jan 13, 2006
    #1
    1. Advertising

  2. Jordan Tiona wrote:
    > [..]
    > void Print(){
    > int i = 1;
    > curData = head;
    >
    > while(true){
    > curData = curData->GetNext();
    > if(curData = NULL)


    Comparison operator is '==', not '='. Here you just assigned NULL
    to 'curData'.

    > break;
    > [...]


    V
     
    Victor Bazarov, Jan 13, 2006
    #2
    1. Advertising

  3. Jordan Tiona

    TB Guest

    Jordan Tiona sade:
    <snip>
    > while(true){
    > curData = curData->GetNext();
    > if(curData = NULL)


    if(curData == NULL)

    > break;
    >

    <snip>
    >
    > I'm getting an access violation error during runtime at the print function,
    > when I'm trying to use the GetXXX accessors.
    >
    > Unhandled exception at 0x0041fc46 in CDDataBase.exe: 0xC0000005: Access
    > violation reading location 0x00000004.
    >
    > What am I doing wrong?
    >


    TB
     
    TB, Jan 13, 2006
    #3
  4. Jordan Tiona wrote:
    > Here is my code.
    >
    > main.cpp:
    >
    > #include "cddb.h"
    >
    > CDData* head;
    > CDData* curData;
    >
    > int main(){
    >
    > head = new CDData();
    > curData = head;
    >
    > EnterInfo();
    > Print();
    > return 0;
    > }
    >
    > void EnterInfo(){
    > CDData* temp;
    > char* input = new char();
    > int ipInt;
    >
    > system("cls");
    >
    > temp = new CDData();
    > curData->SetNext(temp);
    > curData = temp;
    >
    > cout << "Please enter information about your new CD.\n";
    > cout << "\nAlbum name: ";
    > cin.getline(input, 25);
    > curData->SetAlbumName(input);
    > cout << "\nArtist name: ";
    > cin.getline(input, 25);
    > curData->SetArtistName(input);
    > cout << "\nYear Released: ";
    > cin >> ipInt;
    > curData->SetYear(ipInt);
    > }
    >
    > void Print(){
    > int i = 1;
    > curData = head;
    >
    > while(true){
    > curData = curData->GetNext();
    > if(curData = NULL)
    > break;
    >
    > cout << "CD #" << i << endl;
    > cout << "Album Name: " << curData->GetAlbumName() << endl;
    > cout << "Artist Name: " << curData->GetArtistName() << endl;
    > cout << "Year Released: " << curData->GetYear() << endl;
    > cout << "-------------------------------------------\n\n";
    >
    > i++;
    > }
    > }
    >
    > cddb.h:
    >
    > #include <iostream>
    > #include <string>
    > using namespace std;
    >
    > void EnterInfo();
    > void Save();
    > void Load();
    > void Print();
    >
    > class CDData {
    > private:
    > CDData *next; //For linked list
    > char* albumName;
    > char* artistName;
    > int year;
    > public:
    > //Constructor/Destructor
    > CDData(){ this->SetNext(NULL);}
    > ~CDData(){}
    > //Accessors
    > char* GetAlbumName(){return this->albumName;}
    > char* GetArtistName(){return this->artistName;}
    > int GetYear(){return year;}
    > CDData* GetNext(){return next;}
    >
    > void SetAlbumName(char* newName){albumName = newName;}
    > void SetArtistName(char* newName){artistName = newName;}
    > void SetYear(int newYear){year = newYear;}
    > void SetNext(CDData* newNext){next = newNext;}
    > };
    >
    > I'm getting an access violation error during runtime at the print function,
    > when I'm trying to use the GetXXX accessors.
    >
    > Unhandled exception at 0x0041fc46 in CDDataBase.exe: 0xC0000005: Access
    > violation reading location 0x00000004.
    >
    > What am I doing wrong?



    CDData::albumName and CCData::artistName are never initialized.
    If you stick with char*, you must implement the copy constructor,
    assignment operator and destructor.

    Most of your problems will solve if you use std::string instead of
    char*.
    Hint: if you want a buffer of 25 characters use
    char* buf = new char[25];
    and don't forget to delete it later
    delete [] buf;

    Why do you declare
    + void EnterInfo();
    + void Save();
    + void Load();
    + void Print();
    in cddb.h if there are implemented in main.cpp.
    Do you really want that every application that uses CDData
    has to provide them?

    Regards, Stephan

    Open source rating and billing engine for communication networks.
     
    =?iso-8859-1?q?Stephan_Br=F6nnimann?=, Jan 13, 2006
    #4
  5. Jordan Tiona

    Jordan Tiona Guest

    New problem. I used strings now instead, and I can only input one word or
    else it closes immediatly. How do I use cin.getline with strings.
     
    Jordan Tiona, Jan 13, 2006
    #5
  6. Jordan Tiona

    TB Guest

    Jordan Tiona sade:
    > New problem. I used strings now instead, and I can only input one word or
    > else it closes immediatly. How do I use cin.getline with strings.
    >
    >


    #include <string>
    #include <iostream>

    int main() {
    std::string s;
    std::getline(std::cin,s);
    std::endl(std::cout);
    std::cout<<s;
    return 0;
    }

    TB
     
    TB, Jan 13, 2006
    #6
  7. Jordan Tiona

    Jordan Tiona Guest

    "TB" <> wrote in message
    news:43c812a0$0$30401$...
    > Jordan Tiona sade:
    >> New problem. I used strings now instead, and I can only input one word or
    >> else it closes immediatly. How do I use cin.getline with strings.

    >
    > #include <string>
    > #include <iostream>
    >
    > int main() {
    > std::string s;
    > std::getline(std::cin,s);
    > std::endl(std::cout);
    > std::cout<<s;
    > return 0;
    > }
    >
    > TB


    I tried this:

    cout << "Please enter information about your new CD.\n";
    cout << "Album name: ";
    cin.ignore();
    cin.getline(&input, 25);
    curData->SetAlbumName(input);
    cout << "Artist name: ";
    cin.ignore();
    cin.getline(&input, 25);
    curData->SetArtistName(input);
    cout << "Year Released: ";
    cin >> ipInt;
    curData->SetYear(ipInt);
    ignore();

    And I'm getting an error:

    c:\Documents and Settings\Jordan\My Documents\Visual Studio Projects\C++
    Course\Workshop 1\CDDataBase\main.cpp(37): error C2664:
    'std::basic_istream<_Elem,_Traits>::_Myt
    &std::basic_istream<_Elem,_Traits>::getline(_Elem *,std::streamsize)' :
    cannot convert parameter 1 from 'std::string *__w64 ' to 'char *'
    with
    [
    _Elem=char,
    _Traits=std::char_traits<char>
    ]

    Are you sure that getline works with strings?
     
    Jordan Tiona, Jan 13, 2006
    #7
  8. Jordan Tiona

    TB Guest

    Jordan Tiona sade:
    > "TB" <> wrote in message
    > news:43c812a0$0$30401$...
    >> Jordan Tiona sade:
    >>> New problem. I used strings now instead, and I can only input one word or
    >>> else it closes immediatly. How do I use cin.getline with strings.

    >> #include <string>
    >> #include <iostream>
    >>
    >> int main() {
    >> std::string s;
    >> std::getline(std::cin,s);
    >> std::endl(std::cout);
    >> std::cout<<s;
    >> return 0;
    >> }
    >>
    >> TB

    >
    > I tried this:
    >
    > cout << "Please enter information about your new CD.\n";
    > cout << "Album name: ";
    > cin.ignore();
    > cin.getline(&input, 25);
    > curData->SetAlbumName(input);
    > cout << "Artist name: ";
    > cin.ignore();
    > cin.getline(&input, 25);
    > curData->SetArtistName(input);
    > cout << "Year Released: ";
    > cin >> ipInt;
    > curData->SetYear(ipInt);
    > ignore();
    >
    > And I'm getting an error:
    >
    > c:\Documents and Settings\Jordan\My Documents\Visual Studio Projects\C++
    > Course\Workshop 1\CDDataBase\main.cpp(37): error C2664:
    > 'std::basic_istream<_Elem,_Traits>::_Myt
    > &std::basic_istream<_Elem,_Traits>::getline(_Elem *,std::streamsize)' :
    > cannot convert parameter 1 from 'std::string *__w64 ' to 'char *'
    > with
    > [
    > _Elem=char,
    > _Traits=std::char_traits<char>
    > ]
    >
    > Are you sure that getline works with strings?
    >
    >


    First: I have no idea what 'input' is unless I read the error messages.
    Second: I don't think you actually read my code.

    I'm not using 'cin.getline()' but 'std::getline()' found in <string>.

    TB
     
    TB, Jan 13, 2006
    #8
  9. Jordan Tiona

    Jordan Tiona Guest

    I'm a bit confused then. Your code is not clear. Please explain it a bit
    better.
     
    Jordan Tiona, Jan 13, 2006
    #9
  10. Jordan Tiona

    Jordan Tiona Guest

    Never mind. I've got that figured out. Last problem... how do I check for
    end of file?
     
    Jordan Tiona, Jan 13, 2006
    #10
  11. Jordan Tiona

    TB Guest

    Jordan Tiona sade:
    > Never mind. I've got that figured out. Last problem... how do I check for
    > end of file?
    >
    >


    #include <fstream>

    int main() {
    std::fstream f(...);
    if(f.eof()) {
    // end of file
    }
    return 0;
    }

    TB
     
    TB, Jan 13, 2006
    #11
  12. Jordan Tiona

    Jordan Tiona Guest

    Is there a way to do this with the stdio FILE struct?
     
    Jordan Tiona, Jan 13, 2006
    #12
  13. Jordan Tiona schrieb:

    > Is there a way to do this with the stdio FILE struct?


    Yes of course, but then you'll need a buffer char[<size>] and prevent
    potential overflows of the buffer.

    Regards, Stephan
     
    =?iso-8859-1?q?Stephan_Br=F6nnimann?=, Jan 13, 2006
    #13
  14. Jordan Tiona

    Jordan Tiona Guest

    Well, I found how to do it online. But now there is a problem with my
    loading function. Could you possibly see what I'm doing? I apologize for
    posting so many problems.

    void Load(){
    FILE* file;
    string filename;
    CDData* temp;
    system("cls");

    cout << "Name of file (without extension): ";
    getline(cin, filename);
    filename += ".dat";
    cout << "\nLoading from " << filename;
    curData = head;
    if((file = fopen(filename.c_str(), "r+b"))!= NULL){
    //We need to delete the old list first
    //First, go to the last node
    while(curData->GetNext()!= NULL)
    curData = curData->GetNext();
    //Then, we go through and delete each node, until we get to the head
    while(curData->GetPrev()!= NULL){ //If it's NULL then this is head
    curData = curData->GetPrev();
    delete curData->GetNext();
    }
    //We keep the head node, and reset its next and prev
    curData->SetNext(NULL);

    //Now that we've deleted the list, we can make a new one.
    while(!feof(file)){
    temp = new CDData;
    curData->SetNext(temp);
    fread(temp, sizeof(temp), 1, file);
    temp->SetPrev(curData);
    curData = temp;
    }
    }
    else
    cout << "Error opening file";
    }
     
    Jordan Tiona, Jan 13, 2006
    #14
  15. Jordan Tiona schrieb:

    > Well, I found how to do it online. But now there is a problem with my
    > loading function. Could you possibly see what I'm doing? I apologize for
    > posting so many problems.
    >
    > void Load(){
    > FILE* file;
    > string filename;
    > CDData* temp;
    > system("cls");
    >
    > cout << "Name of file (without extension): ";
    > getline(cin, filename);
    > filename += ".dat";
    > cout << "\nLoading from " << filename;
    > curData = head;
    > if((file = fopen(filename.c_str(), "r+b"))!= NULL){
    > //We need to delete the old list first
    > //First, go to the last node
    > while(curData->GetNext()!= NULL)
    > curData = curData->GetNext();
    > //Then, we go through and delete each node, until we get to the head
    > while(curData->GetPrev()!= NULL){ //If it's NULL then this is head
    > curData = curData->GetPrev();
    > delete curData->GetNext();
    > }
    > //We keep the head node, and reset its next and prev
    > curData->SetNext(NULL);
    >
    > //Now that we've deleted the list, we can make a new one.
    > while(!feof(file)){


    feof(FILE*) returns true only after the EOF was read ...

    > temp = new CDData;
    > curData->SetNext(temp);
    > fread(temp, sizeof(temp), 1, file);


    .... so fread will sooner or later fail.
    (Even worse, in case of an error in `file' you could get
    an endless loop because the "EOF"-flag is never set).

    You can't read directly into temp: what is sizeof(temp) if
    CDData::name is 1024 bytes long?
    You must read/write each member indiviually
    (thus my hint char buf[1024]).

    > temp->SetPrev(curData);
    > curData = temp;
    > }
    > }
    > else
    > cout << "Error opening file";
    > }


    Better: provide input/output operator for CDData and use C++ streams.

    Regards, Stephan
     
    =?iso-8859-1?q?Stephan_Br=F6nnimann?=, Jan 13, 2006
    #15
  16. Jordan Tiona

    Jordan Tiona Guest

    "Stephan Brönnimann" <> wrote in message
    news:...
    > Jordan Tiona schrieb:
    >
    >> Well, I found how to do it online. But now there is a problem with my
    >> loading function. Could you possibly see what I'm doing? I apologize for
    >> posting so many problems.
    >>
    >> void Load(){
    >> FILE* file;
    >> string filename;
    >> CDData* temp;
    >> system("cls");
    >>
    >> cout << "Name of file (without extension): ";
    >> getline(cin, filename);
    >> filename += ".dat";
    >> cout << "\nLoading from " << filename;
    >> curData = head;
    >> if((file = fopen(filename.c_str(), "r+b"))!= NULL){
    >> //We need to delete the old list first
    >> //First, go to the last node
    >> while(curData->GetNext()!= NULL)
    >> curData = curData->GetNext();
    >> //Then, we go through and delete each node, until we get to the head
    >> while(curData->GetPrev()!= NULL){ //If it's NULL then this is head
    >> curData = curData->GetPrev();
    >> delete curData->GetNext();
    >> }
    >> //We keep the head node, and reset its next and prev
    >> curData->SetNext(NULL);
    >>
    >> //Now that we've deleted the list, we can make a new one.
    >> while(!feof(file)){

    >
    > feof(FILE*) returns true only after the EOF was read ...
    >
    >> temp = new CDData;
    >> curData->SetNext(temp);
    >> fread(temp, sizeof(temp), 1, file);

    >
    > ... so fread will sooner or later fail.
    > (Even worse, in case of an error in `file' you could get
    > an endless loop because the "EOF"-flag is never set).
    >
    > You can't read directly into temp: what is sizeof(temp) if
    > CDData::name is 1024 bytes long?
    > You must read/write each member indiviually
    > (thus my hint char buf[1024]).
    >
    >> temp->SetPrev(curData);
    >> curData = temp;
    >> }
    >> }
    >> else
    >> cout << "Error opening file";
    >> }

    >
    > Better: provide input/output operator for CDData and use C++ streams.
    >
    > Regards, Stephan
    >


    What do you mean I/O operator for CDData? I'm sorry, I guess I'm more of a
    newbie than I thought.
     
    Jordan Tiona, Jan 14, 2006
    #16
  17. Jordan Tiona wrote:

    > What do you mean I/O operator for CDData? I'm sorry, I guess I'm more of a
    > newbie than I thought.


    std::eek:stream& operator>>(std::eek:stream& os, const CDData& cdData);
    and similar for the input operator of CDData to write/read CDData
    to/from files.

    Regards, Stephan
     
    =?iso-8859-1?q?Stephan_Br=F6nnimann?=, Jan 14, 2006
    #17
    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. Zhao
    Replies:
    3
    Views:
    503
    Robert Olofsson
    Oct 11, 2003
  2. Flip
    Replies:
    2
    Views:
    321
  3. Jarma
    Replies:
    0
    Views:
    306
    Jarma
    Aug 29, 2003
  4. Mark A. Gibbs

    accessors

    Mark A. Gibbs, Aug 18, 2004, in forum: C++
    Replies:
    12
    Views:
    845
    Alf P. Steinbach
    Aug 19, 2004
  5. Tsunami Scripter

    problem with accessors and dsl's

    Tsunami Scripter, Jan 29, 2009, in forum: Ruby
    Replies:
    2
    Views:
    115
    David A. Black
    Jan 29, 2009
Loading...

Share This Page