Here is the header for a class I started:
#ifndef CANVAS_
#define CANVAS_
#include <iostream>
#include <iomanip>
#include <string>
#include <stack>
class Canvas
{
public:
Canvas();
void Paint(int R, int C, char Color);
const int Nrow;
const int Ncol;
string Title;
int image[][100];
stack<int> path;
struct PixelCoordinates
{
unsigned int r;
unsigned int c;
} position;
Canvas operator<< (const Canvas& One );
Canvas operator>>( Canvas& One );
};
/*-----------------------------------------------------------------------------
Name: operator<<
Purpose: Put a Canvas into an output stream
-----------------------------------------------------------------------------*/
ostream& operator<<( ostream& Out, const Canvas& One )
{
Out << One.Title << endl;
Out << "Rows: " << One.Nrow << " Columns: " << One.Ncol << endl;
int i,j;
for( i=0; i<One.Nrow; i++)
{
cout<<"\n\n\n";
cout<< " COLUMN\n";
cout<< " 1 2 3";
for(i=0;i<One.Nrow;i++)
{
cout<<"\nROW "<<i+1;
for(j=0;j<One.Ncol;j++) cout<< One.image[i][j];
}
}
return Out;
}
/*-----------------------------------------------------------------------------
Name: operator>>
Purpose: Get a Canvas from an input stream
-----------------------------------------------------------------------------*/
istream& operator>>( istream& In, Canvas& One )
{
// string Line;
// int Place = 0;
// {
// In >> Line;
// if (In.good())
// {
// One.image[Place][0] = Line;
// Place++;
// }
// return In;
#endif
Here is my implementation file for class Canvas:
using namespace std;
#include <iostream>
#include <iomanip>
#include <string>
#include <stack>
#include "proj05.canvas.h"
//----------------Constructor----------------//
Canvas::Canvas()
{
Title = "";
Nrow = 0;
Ncol = 0;
image[][100] = {};
position.r = 0;
position.c = 0;
}
//-------------------Paint------------------//
void Canvas::Paint(int R, int C, char Color)
{
cout << "Paint to be implemented" << endl;
}
And the errors I'm getting are these:
proj05.canvas.cpp: In function 'std::istream& operator>>(std::istream&, Canvas&)':
proj05.canvas.cpp:11: error: expected `;' before '{' token
proj05.canvas.cpp:24: error: expected `}' at end of input
From my limited experience, they look like simple syntax errors but for the life of me, I cannot see what I am missing. I know putting a ; at the end of Canvas::Canvas() is wrong but that seems to be what it expects. Could someone please clarify for me?
(Also, I know much of the code for the << and >> operator definitions look terrible, but unless that is the specific reason for the error please do not address it. This is a draft :) )
You're missing a } for istream& operator>>( istream& In, Canvas& One ) in the header.
The data member int image[][100]; is also invalid, as is image[][100] = {}; in the ctor.
Your implementation (.cpp) files should #include their corresponding header first. This is a simple way to ensure the header is self-contained. In this case, it would lead to syntax errors in standard library headers, which quickly points out to you the problem is in the header (since that is what will be before the stdlib #includes).
You are missing a closing } for your operator>> body. Also, this is not correct:
using namespace std;
#include <iostream>
The order has to be the other way around. GCC's behavior isn't conforming: std must not be visible if no standard header is included yet. So on the next more conformant compiler, it may fail hard.
Also, in the header you should write std::istream instead of just istream (same for ostream, etc). In your current code, your header relies on its users to have typen using namespace std; before including it, which is pretty ugly from a design point of view, since it makes the headers dependent on its users in a non-obvious way (normally, it should be the other way around).
You do not have a closing } at the end of operator >>
Others have answered your question, but here are a couple of extra points:
If your definitions of the insertion and extraction operators aren't templated then you should move them to your implementation file and merely declare them in the header file. This will allow you to replace the line
#include <iostream>
with the line
#include <iosfwd>
The latter will only include declarations of the IO streams, not the entire definitions. This in turn will translate to a faster compilation time of every compilation unit that includes that header.
On the other hand, you could as well choose to leave those functions in the header file but template them.
template <typename Ch,typename Tr>
std::basic_istream<Ch,Tr>& std::operator>>(std::basic_istream<Ch,Tr>& in,
Canvas& o)
{
// ...
}
This will give you the extra flexibility of supporting any stream at the cost of the same increased compilation time you have now.
There is also an error in the way You initialize constant members of Your class.
You have to use an initialization list
Canvas::Canvas()
: Nrow(0), Ncol(0)
{
Title = "";
//Nrow = 0; - this is an attempt to change the value of a const, which was already constructed.
//Ncol = 0; - same as above
//image[][100] = {};
position.r = 0;
position.c = 0;
}
Related
I have a issue about my constructor is not correctly working. Whenever i run the program, my overloaded operator might not be perform correctly because i always get the default constructor values when i get the output with cout.
I believe that i made my constructor declarations well but all of my objects getting filled with 0 and Unknown
here is my txt file:
1 Prince Heins 25
2 Lady Bridgette 29
3 Tony Ann 223
4 Lucy Phoenix 35
Here is my code;
#include <iostream>
#include <string>
#include <conio.h>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <sstream>
#include <istream>
#include <iomanip>
#include <cstring>
#include <ostream>
using namespace std;
class contact{
private:
int listno;
string name;
string surname;
string phonenumber;
public:
contact(){
this->name="Unknown";
this->surname="Unknown";
this->phonenumber="Unknown";
this->listno=0;
}
contact (string name,string surname,string phonenumber){
this->name=name;
this->surname=surname;
this->phonenumber=phonenumber;
}
contact(int listno,string name,string surname,string phonenumber){
this->name=name;
this->surname=surname;
this->listno=listno;
this->phonenumber=phonenumber;
}
friend ostream & operator<< (ostream &out, const contact &con){
out << con.listno << con.name << con.surname << con.phonenumber;
return out;
}
friend istream & operator>> (istream &in, contact &con){
in >> con.listno >> con.name >> con.surname >> con.phonenumber;
return in;
}
};
int main(){
ifstream pbin("phoneData2.txt");
string line;
long linecount;
for(linecount=0;getline(pbin,line);linecount++);
contact* myArray = new contact[linecount];
pbin.seekg(0);
if(pbin.is_open()){
int i;
for(i=0;i<linecount;i++){
if(pbin!=NULL){
while(pbin>>myArray[i]);
}
}
pbin.close();
cout << myArray[2]; // try attempt
return 0;
}
}
and here is my output for cout << Array[2];
OutputArray2
The problem results from the wrong used algorithm and wrongly placed statements.
So, let's look what is going on in the below:
long linecount;
for(linecount=0;getline(pbin,line);linecount++)
;
contact* myArray = new contact[linecount];
pbin.seekg(0);
if(pbin.is_open()){
int i;
for(i=0;i<linecount;i++){
if(pbin!=NULL) {
while(pbin>>myArray[i]);
}
}
pbin.close();
You want to count the lines. So you read all lines until the eofstate is set. But, additionally, also the fail bit will be set. See also here.
If you use your debugger, you will find a 3 in _Mystate.
Then you perform a seekg. This will reset the eof bit but keep the fail bit. The dubugger shows then
You can see that the fail bit is still set.
So, and this will now lead to the main problem. If your write if(pbin!=NULL) which is definitely wrong (on my machine is does not even compile), or if you better write if(pbin) the fail bit will still be set. And because the bool and the ! operator for streams is overwritten (please see here) the result of the if and while will be false and your pbin>>myArray[i] will never be executed.
So, a pbin.clear() would help.
But, although your class definition is already very good, with inserter and extractor overwritten, you do not use the full C++ power for reading the data.
One basic recommendation would be to never use raw pointers for owned memory. And best also not new. Use dedicated containers for your purpose. E.g. a std::vector. The you can use the std::vectors constructor no 5 together with a std::istream_iterator. Please read here. The range based constructor for the std::vector will copy data from a given range, denoted by the begin and end iterator. And if you use the std::istream_iterator, it will call your overwritten extractor operator, until all data are read.
So your main shrinks to:
int main() {
// Open source file and check, if it could be opened
if (ifstream pbin("r:\\phoneData2.txt");pbin) {
// Read complete source file
std::vector data(std::istream_iterator<contact>(pbin), {});
// Show data on console
std::copy(data.begin(), data.end(), std::ostream_iterator<contact>(std::cout, "\n"));
}
return 0;
}
This looks by far compacter and is easier to read. We start with an if-statement with initializer. The initializer parts defines the variable and the constructor will open the file for us. In the condition part, we simple write pbin. And, as explained above, its bool operator will be called, to check if everything was ok.
Please note:
We do not need a close statement, because the destructor of the
std::ifstream will close the file for us.
The outer namespace will not be polluted with the variable name pbin. That is one of the reasons, why ifstatement with initializer should be used.
We alread descibed the std::vector with its range constructor. SO reading the complete file is simple done by the very simple statement
std::vector data(std::istream_iterator<contact>(pbin), {});
Please note:
We do not define the type of the std::vector. This will be automatically deduced by the compiler through CTAD
We use the default initialzer {} for the end iterator, as can be seen here in constructor number 1.
The whole program could then be rewritten to:
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;
class contact {
private:
int listno;
string name;
string surname;
string phonenumber;
public:
contact() {
this->name = "Unknown";
this->surname = "Unknown";
this->phonenumber = "Unknown";
this->listno = 0;
}
contact(string name, string surname, string phonenumber) {
this->name = name;
this->surname = surname;
this->phonenumber = phonenumber;
}
contact(int listno, string name, string surname, string phonenumber) {
this->name = name;
this->surname = surname;
this->listno = listno;
this->phonenumber = phonenumber;
}
friend ostream& operator<< (ostream& out, const contact& con) {
out << con.listno << '\t' << con.name << '\t' << con.surname << '\t' << con.phonenumber;
return out;
}
friend istream& operator>> (istream& in, contact& con) {
in >> con.listno >> con.name >> con.surname >> con.phonenumber;
return in;
}
};
int main() {
// Open source file and check, if it could be opened
if (ifstream pbin("r:\\phoneData2.txt");pbin) {
// Read complete source file
std::vector data(std::istream_iterator<contact>(pbin), {});
// Show data on console
std::copy(data.begin(), data.end(), std::ostream_iterator<contact>(std::cout, "\n"));
}
return 0;
}
I'm making a car design program. For this program, we are making a class in a header file, and then we will use that header file in our main program by including the file using #include "name of header".
This is my professors header. This is the code in his header. We were instructed to do the header like he is.
/*
Program 14-2
author - Ray Warren, modified from Language Companion
last updated - 19 July 2013
*/
#include <string>
using namespace std;
class CellPhone
{
private:
// Field declarations
string manufacturer;
string modelNumber;
double retailPrice;
public:
// Constructor
CellPhone(string manufact, string modNum, double retail)
{
manufacturer = manufact;
modelNumber = modNum;
retailPrice = retail;
}
// Member functions
void setManufacturer(string manufact)
{
manufacturer = manufact;
}
void setModelNumber(string modNum)
{
modelNumber = modNum;
}
void setRetailPrice(double retail)
{
retailPrice = retail;
}
string getManufacturer()
{
return manufacturer;
}
string getModelNumber()
{
return modelNumber;
}
double getRetailPrice()
{
return retailPrice;
}
}; //end class
This is the program he used the header file in (as you see he included the header file).
/*
Program14-2
author - Ray Warren, modified from Language Companion
last updated - 19 July 2013
*/
#include <iostream>
#include <cstdlib>
#include "CellPhone.hpp"
using namespace std;
int main()
{
// Create a CellPhone object and initialize its
// fields with values passed to the constructor.
CellPhone myPhone("Motorola", "M1000", 199.99);
// Display the values stored in the fields.
cout << "The manufacturer is "
<< myPhone.getManufacturer() << endl;
cout << "The model number is "
<< myPhone.getModelNumber() << endl;
cout << "The retail price is "
<< myPhone.getRetailPrice() << endl;
system("Pause");
return 0;
} //end main
This is my header file containing my class.
#include <string>
using namespace std;
Car(int ym, string mk)
{
yearModel=ym;
make=mk;
speed=0;
}
void setYearModel(int ym)
{
yearModel=ym;
}
void setMake (string mk)
{
make=mk;
}
int returnYearModel()
{
return yearModel;
}
string returnMake()
{
return make;
}
int returnSpeed()
{
return speed;
}
void accelerate()
{
speed += 5;
}
void brake()
{
This is my main program with me attempting to include the header file into my main program. When I tried to compile this, my header file popped up in a new code blocks IDE tab, and gave me this list of errors.
http://prntscr.com/bzu4x5 <--------- list of errors
I have no idea what I'm doing wrong. From what I see, I copied my professor exactly as he told us to, and I'm still getting errors.
Does anyone have any ideas of what's causing this massive list of errors?
#include <string>
#include <iostream>
#include "Car header.h"
int main()
{
}
Your "header file" contains the definitions of the class member functions. It should actually be a .cpp file. What you are missing is a definition of the class itself, and declarations of the member functions.
Note that your professor's sample header file defines the member functions inside the class definition. This is actually poor practise, but he may not have got round to teaching you how do define functions out of line yet.
If you are going to define the functions out of line, you will also need to change the functions to some thing like:
std::string Car::returnMake()
{
return make;
}
Note: "using namespace std" is also poor practise. Professional C++ code tends to be explicit, and use the "std::" prefix. Just get in the habit and save yourself hours of pain.
You did not actually define a class in you header file. Notice that in your teacher's header file, he has:
class Cellphone // -> this is what you do not have
{
private:
// Field declarations
string manufacturer;
string modelNumber;
double retailPrice;
public:
//constructor function
CellPhone(string manufact, string modNum, double retail);
// Member functions
void setManufacturer(string manufact);
void setModelNumber(string modNum);
void setRetailPrice(double retail);
string getManufacturer();
string getModelNumber();
double getRetailPrice();
}
You should have you fields and member functions inside your class. Hope that helps
I have spent a great deal of time in google trying to figure out how to pass a vector when using .h and .cpp files between a call in main and a function in an includes block. I was successful using class definitions.
Now everything is going fine until I want to create an overloaded function. (I could have done this with two different classes, but I must use one overloaded function in my program.)
Here is my writeData.h file:
#ifndef WRITEDATA_H
#define WRITEDATA_H
#include <vector>
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
class writeData
{
public: writeData();
public: writeData(vector<int> & DATAFILE);
public: writeData(vector<int> & DATAFILE, string);
};
#endif
The placement of the using namespace std; is another topic.
Here is my writeData.cpp file:
#include "writeData.h"
writeData::writeData()
{
std::cout << "Default writeData" << std::endl;
}
writeData::writeData(vector<int> & DATAFILE)
{
cout << "writeData 1" << endl;
for (int var : DATAFILE)
{
cout << var <<endl;
}
}
writeData::writeData(vector<int> & DATAFILE, string fileName)
{
ofstream myfile(fileName);
cout << "writeData" << endl;
if (myfile.is_open())
{
for (int var : DATAFILE)
{
cout << var << endl;
myfile << var << endl;
}
myfile.close();
}
}
And here is my main function:
#include <iostream>
#include <vector>
#include <string>
#include "writeData.h"
using namespace std;
int main()
{
string fileName = "test.txt";
vector<int> items{ 10, 14, 22, 34 };
writeData();//default
///////////////////////////////////////////////////
// the next line is the problem code:
//writeData(items);//writes to screen only
//<<When I uncomment it the compiler Tosses the following:
// 'items': redefinition; different basic types
////////////////////////////////////////////////////
writeData(items, fileName);//writes to screen and to file
cin.ignore();
cin.get();
}
The offending line is writeData(items);
Any assistance or pointers to online articles would be most appreciated.
The immediate issue is that this declaration
writeData(items);
is the same as
writeData items;
hence the redefinition error. The deeper issue is that you have defined three constructors for a class, and seem to be attempting to call them without making a named instance. To succesfully call the one parameter constructor passing items, you'd need something like
writeData data_writer(items);
Alternatively, you may want either member functions, or non-members. The choice would depend on whether you really want to model a class, which maintains certain invariants or not. An example of members,
class writeData
{
public:
void write_data() const;
void write_data(const vector<int> & DATAFILE) const;
void write_data(const vector<int> & DATAFILE, string) const;
};
Then
WriteData wd;
wd.write_data(items);
Example of non-members:
namespace writeData
{
void write_data();
void write_data(const vector<int> & DATAFILE);
void write_data(const vector<int> & DATAFILE, string);
};
Then
writeData::write_data(items);
Note I have made the vector<int> parameters const reference because they are not being moified in the functions.
Hey guys I'm working on a project and I was doing pretty well until I hit this wall..
I am getting two errors:
error: 'binarySearch' was not declared in this scope
error: 'addInOrder' was not declared in this scope
Here are my files, I've tried quite a few things with no avail. Help would be much appreciated.
histogram.cpp
#include "histogram.h"
#include "countedLocs.h"
//#include "vectorUtils.h"
#include <string>
#include <vector>
using namespace std;
void histogram (istream& input, ostream& output)
{
// Step 1 - set up the data
vector<CountedLocations> countedLocs;
// Step 2 - read and count the requested locators
string logEntry;
getline (input, logEntry);
while (input)
{
string request = extractTheRequest(logEntry);
if (isAGet(request))
{
string locator = extractLocator(request);
int position = binarySearch (countedLocs,
CountedLocations(locator, 0));
/** Hint - when looking CountedLocations up in any kind
of container, we really don't care if the counts match up
or not, just so long as the URLs are the same. ***/
if (position >= 0)
{
// We found this locator already in the array.
// Increment its count
++countedLocs[position].count;
}
else
{
// This is a new locator. Add it.
CountedLocations newLocation (locator, 1);
addInOrder (countedLocs, newLocation);
}
}
getline (input, logEntry);
}
// Step 3 - write the output report
for (int i = 0; i < countedLocs.size(); ++i)
output << countedLocs[i] << endl;
}
countedLocs.cpp
#include "countedLocs.h"
#include <iostream>
#include <vector>
using namespace std;
int CountedLocations::binarySearch(const vector<CountedLocations> list, CountedLocations searchItem)
{
//Code was here
}
int CountedLocations::addInOrder (std::vector<CountedLocations>& vectr, CountedLocations value)
{
//Code was here
}
countedLocs.h
#ifndef COUNTEDLOCATIONS
#define COUNTEDLOCATIONS
#include <iostream>
#include <string>
#include <vector>
struct CountedLocations
{
std::string url;
int count;
CountedLocations (){
url = "";
count = 0;
}
CountedLocations(std::string a, int b){
url = a;
count = b;
}
int addInOrder (std::vector<CountedLocations>& vectr, CountedLocations value);
int binarySearch (const std::vector<CountedLocations> list, CountedLocations searchItem);
};
inline
std::ostream& operator<< (std::ostream &out, CountedLocations& cL)
{
//out << "URL: " << cL.url << " count: " << cL.count << std::endl;
out << "\"" << cL.url << "\"," << cL.count;
return out;
}
#endif
The methods are member methods of CountedLocations... use something.extractLocator and something.binarySearch or make the histogram() to be also a member method of CountedLocations... (something is of type CountedLocations highly possibly will be countedLocs[position])
You have a free function histogram in which you are trying to use two member functions, addInOrder and binarySearch. In order to use them, you need to have an instance of CountedLocations.
If these are some kind of helper functions, which do not depend on the actual CountedLocations instance, I would turn them into static functions like this (you only need to change the header):
static int addInOrder (std::vector<CountedLocations>& vectr, CountedLocations value);
And then you can call this function by specifying the type of your class:
CountedLocations::addInOrder(...);
You are trying to call member methods of a struct without an object of that type. Strange.
You need to look at what a namespace is.
You declare a class CountedLocations, so far so good. But then you try to use the member functions outside the CountedLocations namespace which will obviously never work.
int position = binarySearch (countedLocs,
CountedLocations(locator, 0));
binarySearch is a member function of the CountedLocations namespace. If you want to call that function you have to create an object that contains a reference to that member function.
CountedLocation myObject;
int position = myObject.binarySearch (countedLocs, CountedLocations(locator, 0));
I dont know if that solves your problem, but you should know this before you even attempt to solve a problem.
Like this function in C:
size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
I've looked in C++ file stream and found this one:
ostream& write ( const char* s , streamsize n );
this one only accepts char* instead of void*
but does it really matter if I use a C-style fwrite function in c++?
Streams are probably what you're looking for unless I misunderstand your question. There are many flavors that handle different jobs, like outputting to a file:
#include <cstdlib>
#include <fstream>
#include <string>
using namespace std;
int main()
{
ofstream f("c:\\out.txt");
const char foo[] = "foo";
string bar = "bar";
int answer = 42;
f << foo << bar<< answer;
return 0;
}
...building strings like you would with printf:
#include <cstdlib>
#include <sstream>
#include <string>
#include <iostream>
using namespace std;
int main()
{
stringstream ss;
const char foo[] = "foo";
string bar = "bar";
int answer = 42;
ss << foo << bar<< answer;
string my_out = ss.str();
return 0;
}
...and they can even handle your own types, if you tell them how:
#include <cstdlib>
#include <string>
#include <iostream>
using namespace std;
class MyGizmo
{
public:
string bar_;
int answer_;
MyGizmo() : bar_("my_bar"), answer_(43) {};
};
ostream& operator<<(ostream& os, const MyGizmo& g)
{
os << g.bar_ << " = " << g.answer_;
return os;
}
int main()
{
MyGizmo gizmo;
cout << gizmo;
return 0;
}
You can use either one. Using char * instead of void * doesn't make much real difference -- both fwrite and ostream::write are typically used for a variety of data types (with with C++, you need to add an explicit cast to char *, where in C the cast will happen implicitly, assuming you've included a proper prototype for fwrite).
In C++ you will want to use std::ofstream objects to write to a file. They can accept any type of data using the << operator, in much the same way that std::cout works for writing to the console. Of course, just like std::cout, if you want to print a custom type, you will need to define an operator<< overload for it.
An example:
std::ofstream outfile("myfile.txt");
int i = 5;
double d = 3.1415926535898;
std::string s = "Hello, World!";
outfile << i << std::endl;
outfile << d << std::endl;
outfile << s << std::endl;
To use std::ofstream, you need to #include <fstream>.
The outfile object will automatically close the file when it destructs, or you can call its close() method.
Contrary to already given answers, there is an important difference between fwrite() and ostream::write().
fwrite() writes binary data unmodified (well, on those poor non-Unix platforms there is endline translation, unless the file is opened in binary mode).
ostream::write() uses locale to transform every character, this is why it accepts char* rather than void*. Normally, it uses the default "C" locale, which does not do any transformation.
Just keep in mind that basic_ostream is a formatter on top of basic_streambuf, not a binary sink.