I am doing a algorithm and data structure exercise in C++ which requires to read a ten-word txt file then display them in a reserved order by using a stack without STL, class or struct. All the code looks good but it display nothing when I actually run it.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int mindex = -1;
string word[10];
void push(string p);
void top();
void pop();
bool isEmpty();
int main()
{
string filename,eli;
cout << "Please input a file name" << endl;
cin>>filename;
ifstream inData;
inData>>eli;
inData.open(filename);
if (!inData)
{
cerr<< "Error opening : " << filename << endl;
return -1;
};
while (inData >> eli)
{
if(inData.fail()){
break; }
else push(eli);
}
while (!isEmpty()){
top();
pop();
}
inData.close();
return 0;
}
void push(string p){
index++;
word[mindex] = p;
}
void pop(){
mindex--;
}
void top(){
cout<<word[mindex]<<" ";
}
bool isEmpty(){
return (mindex<0);
}
There are several mistakes and assumptions here that could go wrong. I will only focus on the immediately obvisous.
#include <iostream>
#include <fstream>
#include <string>
using namespace std; // only for demos/slideware/toy projects.
int mindex = -1;
string word[10]; // we will only ever get 10 strings?
// 10 is a magic number use a const like const int maxWords = 10;
// using std::array will catch problems like this, std::vector can be used to dynamically resize the array.
void push(string p);
void top();
void pop();
bool isEmpty();
int main() {
string filename,eli;
cout << "Please input a file name" << endl;
cin>>filename;
ifstream inData;
inData>>eli; // reading from not open file!!!
inData.open(filename);
if (!inData) {
cerr<< "Error opening : " << filename << endl;
return -1;
};
while (inData >> eli) {
if(inData.fail()) {
break;
} else
push(eli);
}
while (!isEmpty()){
top();
pop();
}
inData.close();
return 0;
}
void push(string p){
index++; // did you mean mindex???
word[mindex] = p; // fatal error if mindex is not at least 0.
}
void pop(){
mindex--;
}
void top(){
cout<<word[mindex]<<" ";
}
bool isEmpty(){
return (mindex<0);
}
A check for mindex at/above 10 should be done somewhere unless you are absolutely sure there will never be more than 10 words.
I have a homework assignment in which I have to code some methods for a linked list and test with a driver from the professor. I keep running into this error:
no matching conversion for functional-style cast from 'int' to 'ItemType'
Here are my files for my "Node" class ItemType:
// ItemType.h.
#include <fstream>
const int MAX_ITEMS = 5;
enum RelationType {LESS, GREATER, EQUAL};
class ItemType{
public:
ItemType();
RelationType ComparedTo(ItemType) const;
void Print(std::ostream&) const;
void Initialize(int number);
private: int value;
};
And ItemType.cpp
#include <fstream>
#include <iostream>
#include "ItemType.h"
ItemType::ItemType()
{
value = 0;
}
RelationType ItemType::ComparedTo(ItemType otherItem) const
{
if (value < otherItem.value)
return LESS;
else if (value > otherItem.value)
return GREATER;
else return EQUAL;
}
void ItemType::Initialize(int number)
{
value = number;
}
void ItemType::Print(std::ostream& out) const
// pre: out has been opened.
// post: value has been sent to the stream out.
{
out << value;
}
When I try to use the professors driver, I get an error with initializing the ItemType class with the constructor. I initialize them like so: classList.putItem(ItemType(4))
But I end up with the error stated above, I'm not sure where Im wrong, here is my driver:
#include "unsorted.h"
using namespace std;
int main() {
UnsortedType classList;
classList.PutItem(ItemType(4));
classList.PutItem(ItemType(5));
classList.PutItem(ItemType(4));
classList.PutItem(ItemType(4));
classList.PutItem(ItemType(8));
cout << "(original) length: " << classList.GetLength() << endl; classList.ResetList();
classList.Print();
classList.ShiftRight();
cout << "(shifted right) length: " << classList.GetLength() << endl; classList.ResetList();
classList.Print();
classList.DeleteItem(ItemType(4));
cout << "(delete all 4s) length: " << classList.GetLength() << endl; classList.ResetList();
classList.Print();
classList.ShiftRight();
cout << "(shift right) length: " << classList.GetLength() << endl; classList.ResetList();
classList.Print();
return 0;
}
You don't have a constructor for ItemType that takes an int. A simple fix would be to define that constructor:
ItemType(int v) : value{v} { }
I've created my code in Microsoft Visual Studio Express 2013 and it compiles and runs fine. I've moved this over to Linux and it gives me a different result for the GPA output. The GPA's are coming as 0 and 6.95281e-310 instead of the 3.9 and 3.5.
Also wondering if there is a difference between the strcmp and strncpy in Linux since I had to add #include <cstring> in my student.h?
Is there something else I should be using instead of strncpy in Linux?
student.h
#ifndef STUDENT_H
#define STUDENT_H
#include <iostream>
#include <cstring>
using namespace std;
class Student
{
public:
Student(const char initId[], double gpa);
bool isLessThanByID(const Student& aStudent) const;
bool isLessThanByGpa(const Student& aStudent) const;
void print()const;
private:
const static int MAX_CHAR = 100;
char id[MAX_CHAR];
double gpa;
};
#endif
student.cpp
#include "student.h"
//implement the required 3 functions here
Student::Student(const char initId[], double gpa) : gpa(gpa)
{
// initialize a newly created student object with the passed in value
strncpy(id, initId, Student::MAX_CHAR - 1);
if (Student::MAX_CHAR > 0)
{
id[Student::MAX_CHAR - 1] = '\0';
}
}
bool Student::isLessThanByID(const Student& aStudent) const
{
// compare the current student object with the passed in one by id.
if (strcmp(id, aStudent.id) > 0)
{
return true;
}
else
{
return false;
}
}
bool Student::isLessThanByGpa(const Student& aStudent) const
{
// compare the current student object with the passed in one by gpa
if (gpa < aStudent.gpa)
{
return true;
}
else
{
return false;
}
}
void Student::print() const
{
cout << id << '\t' << gpa << endl;
}
app.cpp
#include "student.h"
int main()
{
Student s1("G10", 3.9);
Student s2("G20", 3.5);
s1.print();
s2.print();
if(s1.isLessThanByID(s2))
{
cout << "about right!" << endl;
}
else
{
cout << "uhmm ..." << endl;
}
if(!s1.isLessThanByGpa(s2))
{
cout << "about right!" << endl;
}
else
{
cout << "uhmm ..." << endl;
}
//system("pause");
return 0;
}
strcmp compares strings http://www.cplusplus.com/reference/cstring/strcmp/
strncpy copies them http://www.cplusplus.com/reference/cstring/strncpy/
There IS a great diff really between them, in Linux and other systems as well.
Not sure where I am at the moment, trying to figure it out. I need to initialize the members in print() const as it is giving me random gibberish. No matter what I try to do, it does not seem to work. Not sure what to even do. Can anyone give me a hand?
*edit: Added in the rest of the code. Forgot it when I submitted the first time.
Student.cpp
#include "student.h"
//implement the required 3 functions here
Student::Student(const char initId[], double gpa)
{
// initialize a newly created student object with the passed in value
}
bool Student::isLessThanByID(const Student& aStudent) const
{
// compare the current student object with the passed in one by id.
if (strcmp(id, aStudent.id) > 0)
{
return true;
}
else
{
return false;
}
}
bool Student::isLessThanByGpa(const Student& aStudent) const
{
// compare the current student object with the passed in one by gpa
if (gpa < aStudent.gpa)
{
return true;
}
else
{
return false;
}
}
void Student::print() const
{
cout << id << '\t' << gpa << endl;
}
student.h
#ifndef STUDENT_H
#define STUDENT_H
#include <iostream>
using namespace std;
class Student
{
public:
Student(const char initId[], double gpa);
bool isLessThanByID(const Student& aStudent) const;
bool isLessThanByGpa(const Student& aStudent) const;
void print()const;
private:
const static int MAX_CHAR = 100;
char id[MAX_CHAR];
double gpa;
};
#endif
app.cpp
#include "student.h"
int main()
{
Student s1("G10", 3.9);
Student s2("G20", 3.5);
s1.print();
s2.print();
if(s1.isLessThanByID(s2))
{
cout << "about right!" << endl;
}
else
{
cout << "uhmm ..." << endl;
}
if(!s1.isLessThanByGpa(s2))
{
cout << "about right!" << endl;
}
else
{
cout << "uhmm ..." << endl;
}
system("pause");
return 0;
}
There is nothing in that code that sets the values of Student::id and Student::gpa. Your constructor has parameters initId and gpa; you should copy those into your object. Based on the declaration of Student that you provided, something this should be appropriate:
Student::Student(const char initId[], double gpa) : gpa(gpa)
{
strncpy(id, initId, Student::MAX_CHAR-1);
id[Student::MAX_CHAR-1] = '\0';
}
I'm reading a book on C++ and was writing out some code to practice using the interface and implementation of a class. I've searched for solutions to my issue for a while to no avail.
I have a class with an enumeration inside of it. While trying to instantiate an object of that class, I am having trouble accessing the enum types outside of the class. I have tried using Book::Horror, Biblo::Horror, Biblo::Book::Horror, Horror, and even things like Biblo::Book::Genre::Horror. Can't seem to get it to let me access the types of the enum for the instantiation of my object in the main.cpp file.
Any help is appreciated! The more complex uses of C++ are still new to me. Here is my source:
book.h
#include <iostream>
#include <string>
using namespace std;
namespace Biblo{
class Book{
public:
enum Genre{
No_Genre, Horror, Comedy, Romance, Mystery
};
// The rest of this header is working fine I think, just this enum
class Invalid{}; // Used for throwing errors
Book(int n_ISBN, int n_copyrightYear, string n_title, string n_author, Genre n_genre);
Book();
// Accessors (non-modifying)
int getISBN() const { return ISBN; }
int getCopyrightYear() const { return copyrightYear; }
string getTitle() const { return title; }
string getAuthor() const { return author; }
string getGenre() const;
// Mutators
void changeAuthor(string newAuthor);
private:
int ISBN;
int copyrightYear;
string title;
string author;
Genre genre;
}; // End Book
// Helper Functions go here
bool operator==(const Book& a, const Book& b);
bool operator!=(const Book& a, const Book& b);
} // End Biblo
and main.cpp
#include <iostream>
#include "book.h"
using namespace std;
int main()
{
Biblo::Book book(100, 2012, "The Walrus", "The Eggman", Book::Horror); // THIS LINE GIVES ERROR
cout << "ISBN: " << book.getISBN() << endl;
cout << "Copyright: " << book.getCopyrightYear() << endl;
cout << "Title: " << book.getTitle() << endl;
cout << "Author: " << book.getAuthor() << endl;
cout << "Genre: " << book.getGenre() << endl;
return 0;
}
Edit: here is the book.cpp file
#include <iostream>
#include "book.h"
#include <string>
namespace Biblo{
Book::Book(int n_ISBN, int n_copyrightYear, string n_title, string n_author, Genre n_genre)
:ISBN(n_ISBN), copyrightYear(n_copyrightYear), title(n_title), author(n_author), genre(n_genre)
{
// constructor
}
Book::Book()
:ISBN(0), copyrightYear(0), title(""), author(""), genre(Genre::No_Genre)
{
// Default constructor
}
// Accessors
string Book::getGenre() const
{
if (Book.genre == Genre::No_Genre)
return "No Genre!";
if (Book.genre == Genre::Horror)
return "Horror";
if (Book.genre == Genre::Comedy)
return "Comedy";
if (Book.genre == Genre::Romance)
return "Romance";
if (Book.genre == Genre::Mystery)
return "Mystery";
}
// Mutators
void Book::changeAuthor(string newAuthor)
{
author = newAuthor;
}
// Helper Functions
bool operator==(const Book& a, const Book& b)
{
if (a.getISBN() != b.getISBN())
return false;
if (a.getCopyrightYear() != b.getCopyrightYear())
return false;
if (a.getTitle() != b.getTitle())
return false;
if (a.getAuthor() != b.getAuthor())
return false;
if (a.getGenre() != b.getGenre())
return false;
return true;
}
bool operator!=(const Book& a, const Book& b)
{
return !(a==b);
}
} // End Biblo
It seems you tried everything but the thing you needed! The enum is nested inside the Book class which is within the Biblo namespace. The code you are looking for is:
int main()
{
Biblo::Book book(100, 2012, "The Walrus", "The Eggman", Biblo::Book::Horror);
return 0;
}
You need to include the enum class. eg.:
Biblio::Book::Genre::Horror
Bunch of things that are going wrong really.
As others mentioned your enum is stashed one level deeper than you think it is, and your complaint about fixing it then producing an undefined reference is probably because at that point you bump into the fact there's nothing much initialized, and if you got past that you are returning items somewhat poorly when it comes to the enumerator.
If you use the right name space, quickly put in an actual implementation for the constructor, and get the most immediate return for your enum (an int might work) it should work, and probably look like this:
#include <iostream>
#include <string>
using namespace std;
namespace Biblo{
class Book{
public:
enum Genre{
No_Genre, Horror, Comedy, Romance, Mystery
};
// The rest of this header is working fine I think, just this enum
class Invalid{}; // Used for throwing errors
Book(int n_ISBN, int n_copyrightYear, string n_title, string n_author, Genre n_genre);
Book();
// Accessors (non-modifying)
int getISBN() const { return ISBN; }
int getCopyrightYear() const { return copyrightYear; }
string getTitle() const { return title; }
string getAuthor() const { return author; }
int getGenre() const { return genre; }
// Mutators
void changeAuthor(string newAuthor);
private:
int ISBN;
int copyrightYear;
string title;
string author;
Genre genre;
}; // End Book
Book::Book(int n_ISBN, int n_copyrightYear, string n_title, string n_author, Genre n_genre){
ISBN = n_ISBN; copyrightYear = n_copyrightYear; title = n_title; author = n_author;
};
}
using namespace std;
int main()
{
Biblo::Book book(100, 2012, "The Walrus", "The Eggman", Biblo::Book::Horror); // THIS LINE GIVES ERROR
cout << "ISBN: " << book.getISBN() << endl;
cout << "Copyright: " << book.getCopyrightYear() << endl;
cout << "Title: " << book.getTitle() << endl;
cout << "Author: " << book.getAuthor() << endl;
cout << "Genre: " << book.getGenre() << endl;
return 0;
}
Are you sue the book you're following isn't discussing details such as initializer lists or something else for constructors concurrent to, or previous to, the subjects you're looking at?
The code looked somewhat incomplete.
Edited in line here on SO, so bear with the poor formatting and the merged h/cpp look :)