-1

I have printed out the array in the main just to test this method works and it does. But when I try to do the same thing in a different class I get errors.

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <fstream>
#include "struct.h"
#include "phoneBook.h"

using namespace std;

int main()
{
    struct contacts info[256];
    phoneTools manipulate;
    fstream phoneBook ("phoneBook.txt");

    if(!phoneBook.is_open())
    {
        cout<< "The file can not be opened";
        cout<< endl;
        cout<< "Terminating!";

        exit(1);
    }

    else
    {
        //populate array of structs
        int i = 0;
        while(!phoneBook.eof())
        {
            phoneBook>> info[i].firstName;
            phoneBook>> info[i].surName;
            phoneBook>> info[i].phoneNumber;
            phoneBook>> info[i].email;
            phoneBook>> info[i].relationship;
            i++;
        }
    }

    manipulate.addContact(info, phoneBook);
}

This is the other class where I get the errors. I will put the headers below, along with the error messages. I also realize I might have some libraries imported that I am not using, but I will. I just have not finished creating all the functions.

#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <fstream>
#include "struct.h"

using namespace std;

void writeStructToDatabase(struct contacts writeContact[], fstream *phoneBook)
{
    //We are passed new array of contacts
    //write this new array to the phonebook file
    int i = 0;
    while(!phoneBook->eof())
    {
        phoneBook<< writeContact[i].firstName;
        phoneBook<< writeContact[i].surName;
        phoneBook<< writeContact[i].phoneNumber;
        phoneBook<< writeContact[i].email;
        phoneBook<< writeContact[i].relationship;
        i++;
    }
}

void showPhoneBook(struct contacts print[])
{
    int num = (sizeof(print) / sizeof(*print));

    cout<< endl;
    cout<< endl;
    for(int i = 0; i < num; i++)
    {
        cout<< print[i].firstName;
        cout<< endl;

        cout<< print[i].surName;
        cout<< endl;

        cout<< print[i].phoneNumber;
        cout<< endl;

        cout<< print[i].email;
        cout<< endl;

        cout<< print[i].relationship;
        cout<< endl;
    }
    cout<< endl;
}

void addContact(struct contacts newContact[], fstream *phoneBook)
{
    int num = (sizeof(newContact) / sizeof(*newContact));

    cout<< "First Name: ";
    cin>> newContact[num].firstName;
    cout<< endl;

    cout<< "Last Name: ";
    cin>> newContact[num].surName;
    cout<< endl;

    cout<< "Phone Number: ";
    cin>> newContact[num].phoneNumber;
    cout<< endl;

    cout<< "Email: ";
    cin>> newContact[num].email;
    cout<< endl;

    cout<< "Relationship: ";
    cin>> newContact[num].relationship;
    cout<< endl;

    writeStructToDatabase(newContact, phoneBook);
}

void deleteContact(struct contacts delContact[], fstream *phoneBook)
{
    string first;
    string last;

    cout<< "First Name: ";
    cin>> first;
    cout<< endl;

    cout<< "Last Name: ";
    cin>> last;
    cout<< endl;

    int num = (sizeof(delContact)/sizeof(*delContact));

    int exit = 0;
    int i = 0;
    while(exit == 0)
    {
        if((strcmp(delContact[i].firstName, first) == 0) &&
           (strcmp(delContact[i].surName, last) == 0))
        {
            for(int j = i; j < num; j++)
            {
                delContact[j] = delContact[j+1];
            }

            exit = 1;
        }

        i++;
    }

writeStructToDatabase(delContact, phoneBook);
}

Here is my header for my struct

#include <string.h>

using namespace std;

#ifndef STRUCT_H
#define STRUCT_H
struct contacts
{
    string firstName;
    string surName;
    string phoneNumber;
    string email;
    string relationship;
};
#endif

Here is the header for my functions class

#include <fstream>

using namespace std;

#ifndef PHONE_BOOK_H
#define PHONE_BOOK_H

//enter methods below this line
//ex. extern void getRandInteger(int max);

class phoneTools
{
    public:
    void addContact(contacts newContact[], fstream *phoneBook);
    void showPhoneBook(contacts print[]);
    void deleteContact(contacts delContact[], fstream *phoneBook);

    private:
    void writeStructToDatabase(contacts writeContact[], fstream *phoneBook);
};

//enter methods above this line

#endif /* __PHONE_BOOK_H */

Now here are the errors I am getting

phoneBook.cpp: In function ‘void writeStructToDatabase(contacts*, std::fstream*)’:
phoneBook.cpp:16: error: no match for ‘operator<<’ in ‘phoneBook << writeContact[i].contacts::firstName’
phoneBook.cpp:17: error: no match for ‘operator<<’ in ‘phoneBook << writeContact[i].contacts::surName’
phoneBook.cpp:18: error: no match for ‘operator<<’ in ‘phoneBook << writeContact[i].contacts::phoneNumber’
phoneBook.cpp:19: error: no match for ‘operator<<’ in ‘phoneBook << writeContact[i].contacts::email’
phoneBook.cpp:20: error: no match for ‘operator<<’ in ‘phoneBook << writeContact[i].contacts::relationship’
phoneBook.cpp: In function ‘void deleteContact(contacts*, std::fstream*)’:
phoneBook.cpp:97: error: cannot convert ‘std::string’ to ‘const char*’ for argument ‘1’ to ‘int strcmp(const char*, const char*)’
phoneBook.cpp:98: error: cannot convert ‘std::string’ to ‘const char*’ for argument ‘1’ to ‘int strcmp(const char*, const char*)’
phoneBookDriver.cpp: In function ‘int main()’:
phoneBookDriver.cpp:40: error: invalid conversion from ‘void*’ to ‘std::fstream*’
phoneBookDriver.cpp:40: error:   initializing argument 2 of ‘void phoneTools::addContact(contacts*, std::fstream*)’
i686-apple-darwin11-llvm-g++-4.2: phoneBook.o: No such file or directory
i686-apple-darwin11-llvm-g++-4.2: phoneBookDriver.o: No such file or directory
i686-apple-darwin11-llvm-g++-4.2: no input files

I have searched for the last day trying to figure out why I am not able to use the fstream functions even though I imported the library, plus I am able to do this in my main. This is my first question here, so I hope I formatted it correctly. Also this is just for fun over the summer. Not homework or anything.

  • 1
    Because `phoneBook` is a pointer. Try `->` instead of `.`. – Oliver Charlesworth Jun 15 '13 at 16:27
  • ohh okay. Thank you. Is it that I am not passing the phoneBook file correctly and this is why I am not able to write to it from phoneBook.cpp? – R.J. McDown Jun 15 '13 at 16:46
  • 1
    [`while (!eof())` is wrong.](http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong) Also, `__STRUCT_H` and `__PHONE_BOOK_H` are [reserved identifiers](http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier). – chris Jun 15 '13 at 16:56

2 Answers2

2

Your second version of the code is not doing the same thing, as you claim. It's using a variable of type ifstream* not a variabel of type ifstream and you're using << to read from it not >>. If you'd done the same thing it would have worked, but you changed it to do something different and broken.

The error does not say eof is not a class type of fstream, read it again more carefully:

phoneBook.cpp:14: error: request for member ‘eof’ in ‘phoneBook’,
    which is of non-class type ‘std::ifstream*’

it says phoneBook is of non-class type ifstream* (i.e. a pointer type) and that you're trying to use a member of it, which is pretty self-explanatory because pointers don't have members.

Just read the error properly and it tells you what's wrong. Read your code more carefully and you'll see for yourself the second version is not equivalent to the first.

Also, as the comment from chris says, do not do this:

#ifndef __PHONE_BOOK_H

names beginning with double-underscore (or underscore and an uppercase letter) are reserved and you must not use them.

And do not do this:

while(!phoneBook.eof())

The loop will exit after failing to read data, which is not what you want, this is you want:

while(*phoneBook >> writeContact[i].firstName >> writeContact[i].surName
      >> writeContact[i].phoneNumber>> writeContact[i].email
      >> writeContact[i].relationship)

(Note using >> not <<)

But why not make it easier to read and define operator>>(std::istream&, contacts&) which would allow you to do simply:

while (*phoneBook >> writeContact[i])

And you could also pass the ifstream by reference not pointer, then you avoid the problems of not using a pointer correctly.

Community
  • 1
  • 1
Jonathan Wakely
  • 153,269
  • 21
  • 303
  • 482
  • **Update** I just changed the code and errors up top to match what I have after making those changes. Again thanks for the help – R.J. McDown Jun 15 '13 at 17:20
  • JONATHAN WAKELY thank you for the detailed reply and the better method of populating my phoneBook. I will start to implement this now. – R.J. McDown Jun 15 '13 at 17:24
0

phoneBook is a pointer use -> instead of . and ifstream means "input file stream" so it can receive input only from the file to your application

you must use "ofstream" or the parent of them "fstream" http://www.cplusplus.com/reference/fstream/fstream/

MOHAMED FATHEI
  • 480
  • 2
  • 5
  • Chris I read stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier. After I read that I removed the double underscores in the header files. So now I have PHONE_BOOK_H for example. Oli I changed my while to while(!phoneBook->eof()) and this fixed the error. Mohamed I changed my declaration of phoneBook from "ifstream" to "fstream" because I need both input and output operations. However, I am still getting those errors. I made sure to change it in the headers and other files as well. Thanks for the help – R.J. McDown Jun 15 '13 at 17:14