So I am very new to C++ and I am having a hard time learning how too implement classes into a function I have. My prof isn't being helpful in any capacity and I am very lost.
So the jist of the program is to take a file "books.txt" where each line contains an author and a book in the following format: Douglas Adams, The Hitchhiker's Guide to the Galaxy
I am trying to get the function to populate an array with "Book" objects with the title and author data from the file. It takes 4 input arguments: a name of the file as a string, an array of "Book" objects, the number of "Book" objects stored in the array of Book, and the capacity of the library system (with a max of 200).
For each line in the file, I am supposed to instantiate a Book object, fill in the author and title data members (listed in the code below), and append the object to the array of "Book" objects and it will return the numbers of books in the system as an integer.
Here is my header file (Book.h):
#include <iostream>
#include <math.h>
#include <string>
#include <string.h>
#include <fstream>
#include <stdio.h>
#include <cctype>
#include <locale>
#include <algorithm>
using namespace std;
#ifndef BOOK_H
#define BOOK_H
class Book{
private: //Member Variables
string author;
string title;
string inauthor;
string intitle;
string input;
string input2;
public:
Book();
Book(string intitle, string inauthor);
string getTitle();
void setTitle(string input);
string getAuthor();
void setAuthor(string input2);
};
#endif
Here is the .cpp file associated with the header file:
#include <iostream>
#include <math.h>
#include <string>
#include <string.h>
#include <fstream>
#include <stdio.h>
#include <cctype>
#include <locale>
#include <algorithm>
#include "Book.h"
using namespace std;
//Default constructor
Book::Book(){
author = "";
title = "";
}
//Parameterized Constructor
Book::Book(string intitle, string inauthor){
}
//An accessor function that returns the name of the title
string Book::getTitle() {
return title;
}
//A function that assigns the value title to the input given by the user
void Book::setTitle(string title){
title = intitle;
}
//An accessor function that returns the name of the author
string Book::getAuthor() {
return author;
}
//A function that assigns the value author to the input given by the user
void Book::setAuthor(string author){
author = inauthor;
}
And finally, here is the function I am trying to place it into (it is incomplete as every previous attempt I have made to use classes ends in a long list of errors and here is where I can confidently say I can get to):
#include <iostream>
#include <math.h>
#include <string>
#include <string.h>
#include <fstream>
#include <stdio.h>
#include <cctype>
#include <locale>
#include <algorithm>
#include "Book.h"
#include "User.h"
using namespace std;
int readBooks (string filename, int books[] , int bookObj, int capacity){
int i = 0;
ifstream file;
file.open (filename);
if (file.fail()){
return -1;
}
else{
string line;
while ((i < books) && (i < capacity) && (getline(file,line))){
}
}
I bet this is probably a very simple problem but neither the book or any other resources I have been referencing has been able to help me very much. Any help or advice would be greatly appreciated! Thank you!
I can help you out with your class design. It would look something like this:
Book.h
#ifndef BOOK_H
#define BOOK_H
#include <string>
#include <vector>
const int LIBRARY_MAX_CAPACITY = 200;
class Book {
private:
std::string author_;
std::string title_;
public:
Book() : author_( "" ), title_( "" ) {}
Book( const std::string& authorIn, const std::string& titleIn ) :
author_( authorIn ), title_( titleIn )
{}
void setAuthor( const std::string& authorIn ) {
this->author_ = authorIn;
// or just author_ = authorIn;
}
void setTitle( const std::string& titleIn ) {
this->title_ = titleIn;
// or just title_ = titleIn;
}
std::string getAuthor() const { return author_; }
std::string getTitle() const { return title_; }
};
void readBooks( const std::string& filename, std::vector<Book>& books );
#endif // BOOK_H
Book.cpp
#include "Book.h"
#include <fstream>
// this is just pseudo code and will not actually compile
void readBooks( const std::string& filename, std::vector<Book>& books ) {
// open file, test if open correctly
std::ifstream file;
file.open( filename );
// loop through file until end is reached by reading in
// a line of code and getting the contents of the book
while ( file still has data && line <= LIBRARY_MAX_CAPACITY ) {
// get a line of text then parse that line of text.
std::string author = "first string from file before comma"
std::string title = "second string from file after comma"
// create a book object here:
Book book( author, title );
// push back into vector that is passed into this function by reference
books.push_back( book );
}
// done with loop close the file
file.close();
}
Now what ever other function calls this function such as main, or your Library class etc. The std::vector<Book> object will be passed back by reference that is already populated with book objects and std::vector<> has a .size() function that returns it's size as an std::size_t.
Related
I'm trying to create a function below called load() that copies all the records from my graduate.dat file into my vector of Record pointers called primaryCollection. I created a Record class with variables that make up each Record, and in my load() function in createReport.cc I attempted to read each line in the file, create a Record object with each line, and then add it to my vector.
The problem is I keep getting the error:
createReport.cc: In static member function ‘static void createReport::load()’:
createReport.cc:25:71: error: expression list treated as compound expression in initializer [-fpermissive]
Record* record(year, province, degree); //create Record object with this data
^
createReport.cc:25:71: error: invalid conversion from ‘int’ to ‘Record*’ [-fpermissive]
I'm not sure why this is and I would appreciate some help trying to read the file add each record to my collection.
My graduate.dat file is formatted like below in the format < year province degree >
2000 AB Bachelor's
2005 AB Bachelor's
2005 MB College
primaryCollection is required to be a vector of record pointers and I'm also not allowed to use std::map in this task.
Record.h
#ifndef RECORD_H
#define RECORD_H
#include <iostream>
#include <string>
class Record{
public:
Record(int = 0, string = "", string = "");
~Record();
private:
int year;
string province;
string degree;
};
#endif
Record.cc
#include <iostream>
#include <string>
using namespace std;
#include "Record.h"
Record::Record(int i1, string s1, string s2) : year(i1), province(s1), degree(s2){}
Record::~Record(){}
createReport.h
#ifndef CREATEREPORT_H
#define CREATEREPORT_H
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>
#include <cstdlib>
#include "Record.h"
class createReport{
public:
createReport();
static void load();
protected:
static vector<Record*> primaryCollection; //STL vector of record pointers
};
#endif
createReport.cc
#include <iostream>
using namespace std;
#include <string>
#include "createReport.h"
void createReport::load(){
int year;
string province, degree;
ostream_iterator<Record*> outItr(cout);
ifstream infile("graduate.dat", ios::in);
if (!infile) {
cout << "Error: could not open file" << endl;
exit(1);
}
while (infile >> year >> province >> degree) { //as long as were not at end of file
Record* record(year, province, degree); //create Record object with this data
primaryCollection.push_back(record);
}
cout<<endl<<"List of Records:"<<endl;
copy(primaryCollection.begin(), primaryCollection.end(), outItr); //print records
}
The correct syntax here is:
Record* record = new Record(year, province, degree);
Everything after that is fine, but keep in mind that vector now "owns" the pointers and you're responsible for releasing those allocations somehow. This is where pointer wrappers come in handy.
I'm replicating the TextQuery example in C++ Primer 5th edition. The code compiles, but it keeps throwing "read access violation" from Vector header when a push_back operation is executed. Here's my code (* is the line with bug):
//main.cpp
#include "stdafx.h"
using namespace std;
int main()
{
ifstream ifile;
ifile.open("D:/OneDrive/Learning/C++/ConsoleApplication1/ConsoleApplication1/testfile.txt");
runQueries(ifile); //*
// ...
}
//stdafx.h
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
#include <vector>
#include <string>
#include <memory>
#include <iostream>
#include <algorithm>
#include <fstream>
#include <iterator>
#include <sstream>
#include <map>
#include <set>
#include "TextQuery.h"
//TextQuery.h
void runQueries(ifstream &infile)
{
TextQuery tq(infile); //*
// ...
}
class TextQuery {
public:
using line_no = std::vector<std::string>::size_type;
TextQuery(std::ifstream&); //*
// ...
private:
std::shared_ptr<std::vector<std::string>> file;
std::map < std::string, std::shared_ptr<std::set<line_no>>> wm;
};
TextQuery::TextQuery(std::ifstream &is)
{
string text;
while (getline(is, text)) {
file->push_back(text); //*
//...
}
}
The next execution will raise an exception in vector header:
bool _Has_unused_capacity() const _NOEXCEPT
{ // micro-optimization for capacity() != size()
return (this->_Myend() != this->_Mylast());
}
Here's the error message:
Exception thrown: read access violation.
std::_Vector_alloc<std::_Vec_base_types<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > >::_Myend(...) returned 0xC.
Here's the text file I used for testing:
//text file
text is good
text is good
text is good
text is good
text is good
text is good
text is good
text is good
text is good
As pointed out by #molbdnilo: I forgot to allocate "file".
After changing the constructor to the following, the problem is solve:
TextQuery::TextQuery(std::ifstream &is):file(new vector<string>)
{
string text;
while (getline(is, text)) {
file->push_back(text); //*
//...
}
}
Error: multiple definition of `GameKey::getGameKeywords()'
GameKey.cpp and .h cause error, while ExitKey.cpp and .h are essentially the exact same class and header but do not produce an error.
(I know the whole thing about using namespace std)
//Function Declarations
#ifndef GAMEKEY_H
#define GAMEKEY_H
// C++ libraries
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>
using namespace std;
class GameKey
{
private:
string keyString;
string lineData;
public:
// Default constructor
GameKey();
// Deconstructor
~GameKey();
// Get keywords
string getGameKeywords();
};
#endif
GameKey.cpp
//Function Definitions
#include "GameKey.h"
// Constructor
GameKey::GameKey()
{
}
// Deconstructor
GameKey::~GameKey()
{
}
// Get keywords
string GameKey::getGameKeywords()
{
ifstream infile;
infile.open("GameKey.txt");
while (getline(infile, lineData))
{
keyString.append(lineData);
keyString.append("\n");
}
infile.close();
return keyString;
}
ExitKey.h
//Function Declarations
#ifndef EXITKEY_H
#define EXITKEY_H
// C++ libraries
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>
using namespace std;
class ExitKey
{
private:
string keyString;
string lineData;
public:
// Default constructor
ExitKey();
// Deconstructor
~ExitKey();
// Get keywords
string getExitKeywords();
};
#endif
ExitKey.cpp
//Function Definitions
#include "ExitKey.h"
// Constructor
ExitKey::ExitKey()
{
}
// Deconstructor
ExitKey::~ExitKey()
{
}
// Get keywords
string ExitKey::getExitKeywords()
{
ifstream infile;
infile.open("ExitKey.txt");
while (getline(infile, lineData))
{
keyString.append(lineData);
keyString.append("\n");
}
infile.close();
return keyString;
}
Thanks for any help!
I think you probably include GameKey.cpp instead of GameKey.h elsewhere
I am not certain as the command used for compilation is not posted.
One possibility is repeating the file names in your compilation command could also lead to this error.
for example :-
g++ ExitKey.cpp GameKey.cpp GameKey.cpp main.cpp -o main
Hi I just started to learn C++ this week and I require some assistance.
Basically what I am trying to do is read from a .txt file and "convert" it into a vector string and then display it.
my error is at this line: text.readFile("scenario.txt"), it says: "request for member 'readFile' in 'text', which is of non-class type 'Conversion()'"
what does that mean?
and also my method getLines() could not be resolved.
main.cpp
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <vector>
#include "Conversion.h"
using namespace std;
int main()
{
vector<string> lines;
Conversion text();
if(text.readFile("scenario.txt") == true)
lines = text.getLines();
for(int i = 0; i < lines.size(); ++i)
cout << lines[i] << endl;
return 0;
}
Conversion.cpp
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include "Conversion.h"
using namespace std;
vector<string> lines;
Conversion::Conversion(std::vector<std::string> lines) {
lines.clear();
}
Conversion::Conversion() {
}
Conversion::~Conversion() {
}
bool Conversion::readFile(string filename) {
ifstream file;
string line;
file.open(filename.c_str());
if(!file.is_open())
return false;
while(getline(file, line))
lines.push_back(line);
return true;
}
vector<string> Conversion::getLines(){
return lines;
}
Conversion.h
#ifndef CONVERSION_H_
#define CONVERSION_H_
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
class Conversion {
public:
Conversion();
Conversion(std::vector <std::string>);
~Conversion();
std::vector<std::string> getLines();
bool readFile(std::string);
private:
std::vector<std::string> lines;
std::string line;
std::ifstream file;
};
#endif
Once again, Conversion text(); is a function declaration, not a class instantiation. To call the default constructor, change it to Conversion text;
You probably wanted to copy the passed lines in your constructor:
Conversion::Conversion(std::vector<std::string> const& lines) : lines(lines) { }
Your code should work now, but there can be done some improvements. To avoid copy, getLines should return by reference-to-const:
std::vector<std::string> const& getLines();
// you don't have to create lines in main, you can print like this:
for(auto const& x : text.getLines())
cout << x << endl;
and I'd use it even here:
bool readFile(std::string const&);
I hope this is the last thing - std::ifstream constructor and open function also take std::string:
file.open(filename);
You need to remove the parentheses when instantiating the Conversion object:
Conversion text;
See this question for detailed answers: Is no parentheses on a constructor with no arguments a language standard?
I have tried every combination of #include statements that I can think of, and nothing is working. I am trying to write a basic inheritance program but i keep getting the error error: expected class-name before '}' token and I just do not know what to do about it anymore. I've tried having my main() include the .cpp file of the Executive class, however this error shows up. The program includes 5 types of employees all inherited from the Employee class, and I'm assuming that they are all the same error:
#include <iostream>
#include <string>
#include "Employee.cpp"
#include "Manager.cpp"
#include "Executive.cpp"
#include "Technical.cpp"
#include "Software.cpp"
#include "Test.cpp"
using namespace std;
int main()
{
Employee emp[3];
Executive emp0("John", "Doe", "VP", 100000.0, 1000000.0, 2000.0);
Software emp1("Vincent", "Giuliana", "Project Leader", 150000.0, 200000.0, 1000.0);
Test emp2("Lauren", "Wallis", "Overseer of Testing", 95000, 115000);
emp[0] = emp0;
emp[1] = emp1;
emp[2] = emp2;
for(int i=0; i<3; i++)
emp[i].displayInformation();
emp0.displayInformation();
emp1.displayInformation();
emp2.displayInformation();
return 0;
}
My Employee.h header file is as follows:
#ifndef EMPLOYEE_H_INCLUDED
#define EMPLOYEE_H_INCLUDED
#include <string>
#include <iostream>
using namespace std;
class Employee
{
private:
string fName, lName, jobTitle;
double baseSalary, salary;
public:
Employee();
Employee(string fName, string lName, string jobTitle, double baseSalary);
void calculateSalary(double baseSalary);
void displayName();
void displayBSalary();
void displayJobTitle();
void displayInformation();
...
getters
...
...
setters
...
};
#endif // EMPLOYEE_H_INCLUDED
My Employee.cpp is:
#include <string>
#include <iostream>
#include "Employee.h"
using namespace std;
Employee::Employee()
{
fName = "";
lName = "";
jobTitle = "";
baseSalary = 000000;
}
...
void Employee::setBSalary(double bs) //sets base salary as parameter
{
baseSalary = bs;
}
The top of the Executive.h header class:
#ifndef EXECUTIVE_H_INCLUDED
#define EXECUTIVE_H_INCLUDED
#include <string>
#include <iostream>
//#include "Employee.h"
using namespace std;
class Executive : public Employee
{
private:
string fName, lName, jobTitle;
double baseSalary, salary, bonus, stockOption;
public:
...
};
#endif // Executive_H_INCLUDED
And last but not least, the Executive.cpp file...
#include
#include
#include "Executive.h"
using namespace std;
Executive::Executive()
{
fName = fN;
lName = lN;
jobTitle = jt;
baseSalary = bs;
bonus = b;
stockOption = so;
}
...
void Executive::setSO(double so) //sets stock option as parameter
{
stockOption = so;
}
I think that I have tried to include each header in each file and still, nothing. Any help would be appreciated, and I thank anyone very much in advance!
You must
#include "Employee.h"
in Executive.h, because the compiler must see the declaration of Employee, when a class inherits from it. So, just remove the comments from the #include