C++ - ofstream overloaded operator '<<' is ambiguous? - c++

I am having trouble solving this error.
Use of overloaded operator '<<' is ambiguous (with operand types 'std::ofstream' (aka 'basic_ofstream') and 'std::string' (aka 'basic_string<char, char_traits, allocator>'))
My first assumption was because of the similar ostream operator, but no luck.
Any help is much appreciated.
maintest.cpp
#include <iostream>
#include <fstream>
#include <string>
#include "player.h"
int main() {
//#########################################################################
// TEST - Overloading Stream Operators
//**************************************************************
// Test ostream & istream
/*std::cout << "\n---ISTREAM/OSTREAM TEST---\n";
Player playerS1;
std::cin >> playerS1;
std::cout << "Test output: ";
std::cout << playerS1;*/
//**************************************************************
// Test ofstream
std::cout << "\n---OFSTREAM TEST---\n";
Player playerS2;
int playerScoreS2(66);
std::string playerNameS2("Tanner");
playerS2.SetName(playerNameS2);
playerS2.SetScore(playerScoreS2);
std::ofstream outFile;
outFile.open("testFile");
if(!outFile.is_open()) {
std::cout << "Could not open file." << std::endl;
}
else {
std::cout << "File opened." << std::endl;
}
outFile << playerS2;
std::cout << "File closed." << std::endl;
outFile.close();
// Return here!!!
return 0;
}
player.h
#ifndef PLAYER_H // MACRO guard
#define PLAYER_H
#include <iostream>
#include <fstream>
#include <string>
class Player {
public:
Player(); // Default constructor
Player(const int &score);
Player(const std::string &name);
Player(const std::string &name, const int &score);
// Output functions
std::string toString() const;
std::string toFileString() const;
friend std::ostream& operator<<(std::ostream& out, const Player& line);
friend std::ofstream& operator<<(std::ofstream& outFS, const Player& line);
friend std::istream& operator>>(std::istream& in, Player& line);
friend std::ifstream& operator>>(std::ifstream& inFS, Player& line);
private:
std::string name;
int score;
};
player.cpp
/*********************
OTHER MEMBER FUNCTIONS
*********************/
std::string Player::toString() const {
// What is the format????
// Using comma delimited for now.
return name + ',' + std::to_string(score);
}
std::string Player::toFileString() const {
return name + ',' + std::to_string(score);
}
/****************************
INPUT/OUTPUT STREAM OPERATORS
****************************/
/*std::ostream& operator<<(std::ostream& out, const Player& line) {
out << line.toString() << std::endl;
return out;
}
std::istream& operator>>(std::istream& in, Player& line) {
std::cout << "\nEnter Name: ";
in >> line.name;
std::cout << "Enter Score: ";
in >> line.score;
return in;
}*/
/*std::ifstream& operator>>(std::ifstream& inFS, Player& line) {
inFS >> line.name >> line.score;
return inFS;
}*/
std::ofstream& operator<<(std::ofstream& outFS, const Player& line) {
outFS << line.toFileString() << std::endl;
return outFS;
}
My assumption, based on the assignment, was that the ostream and ofstream operators were essentially the same but using two different functions outputing in different formats. (They currently output the same format).
Any advice?

Related

Writing to an array class will not cout

The code runs, but I cannot get cout to work. Please help me, I am a beginner, and really struggling with getting the contents of my array to output.
cout << myArray[0].getSquareName(); is the line that never cout's.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
class cSquare {
public:
string SquareName;
string getSquareName() const;
void setSquareName(string);
friend std::istream & operator >> (std::istream & is, cSquare & s);
};
// set method
void cSquare::setSquareName(string squareName)
{
squareName = SquareName;
}
//square name get method
string cSquare::getSquareName() const
{
return SquareName;
}
ostream & operator << (ostream & os, const cSquare & s)
{
os << s.getSquareName() << ' ';
return os;
}
istream & operator >> (istream & is, cSquare & s)
{
is >> s.SquareName;
return is;
}
int main()
{
string discard;
int i = 0;
const int MAX_SIZE = 26;
ifstream monopoly("monopoly.txt", ios::in);
if (monopoly.is_open())
{
cSquare myArray[MAX_SIZE];
getline(monopoly, discard);
string sname; //string to store what I read in from my file
while (i < MAX_SIZE && monopoly >> sname)
{
myArray[i].setSquareName(sname);//stores the string read in into the array
cout << myArray[0].getSquareName(); //it never cout's this
i++;
}
}
}
Your setSquareName() method is assigning the object's SquareName member to the input parameter, which is wrong. You need to do the opposite instead, eg:
void cSquare::setSquareName(string sname)
{
//sname = SquareName;
SquareName = sname;
}
Also, this line:
cout << myArray[0].getSquareName();
Should be this instead:
cout << myArray[i];
With those 2 changes, the code works.
Demo

fread is reading garbage in file

I am working on my assignment and faced a problem with fread() in C++. When I modify the name in my file it modifies it perfectly as I want but the problem occurs when I try to read the file after that, it reads the whole file but it does not stop after that it's running total 146 times whereas there are only 3 names.
My code:-
#include <bits/stdc++.h>
using namespace std;
struct person{
int id;
string fname;
}s;
void write(){
FILE *outfile;
struct person input;
int num,ident;
string sname[] = {"a","b","c"};
outfile = fopen ("C:\\Users\\Amritesh\\Desktop\\students.txt","wb");
if (outfile == NULL)
{
fprintf(stderr, "\nError opend file\n");
exit (1);
}
scanf("%d",&num);
for(int i=0;i<num;i++){
s.fname = sname[i];
cin >> s.id;
fwrite (&s, sizeof(s), 1, outfile);
}
fclose(outfile);
}
void read(){
FILE *file1;
int i=0;
file1 = fopen ("C:\\Users\\Amritesh\\Desktop\\students.txt","r");
while(fread(&s, sizeof(s), 1, file1) == 1) {
cout << "ID " << s.id << " Name " <<s.fname << endl;
}
fclose (file1);
}
void modify(){
FILE *file;
file = fopen ("C:\\Users\\Amritesh\\Desktop\\students.txt","r+");
while(fread(&s, sizeof(s), 1, file)) {
if(s.fname == "a"){
s.fname = "d";
fseek(file,-sizeof(s),SEEK_CUR);
fwrite (&s, sizeof(s), 1,file);
}
}
fclose (file);
}
int main(){
write();
modify();
read();
}
Edited code:-
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
struct person
{
int id;
string fname;
}s,temp;
void read()
{
int num;
ifstream fin;
fin.open("C:\\Users\\Amritesh\\Desktop\\student.txt",ios::in);
fin.seekg(0,ios::beg);
//scanf("%d",&num);
while(fin){
cout << s.fname << s.id << endl;
}
fin.close();
}
void write(){
int i=0;
ofstream fout;
fout.open("C:\\Users\\Amritesh\\Desktop\\student.txt");
while(i!=2) {
cin >> s.id >> s.fname;
fout << "ID " << s.id << " Name " <<s.fname << endl;
i++;
}
fout.close();
}
void modify(){
fstream mod;
mod.open ("C:\\Users\\Amritesh\\Desktop\\student.txt");
while(mod) {
if(s.fname == "a"){
s.fname = "d";
mod.seekg(-sizeof(s),ios::cur);
mod << s.fname;
}
}
mod.close();
}
int main(){
write();
read();
modify();
}
Thanks for any answer!
Here are three ideas based on our discussion. I'll start with free functions for reading and writing a person object since it looks like you're at that stage right now. I'll move on to adding member functions in your person class and end with adding stream operators for convenience.
An example of free (non-member) read and write functions:
#include <iostream>
#include <string>
#include <fstream>
struct person {
int id;
std::string fname;
};
std::ostream& write(std::ostream& os, const person& p) {
os << p.id << ',' << p.fname << '\n'; // stream out the properties of a person
return os; // look at the next example for an alternative doing the same thing
}
std::istream& read(std::istream& is, person& p) {
// extract "id" and if it succeeds, check if the next char is a , char
if(is >> p.id && is.peek() == ',') {
is.ignore(); // step over the , char
std::getline(is, p.fname); // read the rest of the line into p.fname
} else {
// we didn't get id or the , char, so set the stream in a failed state
is.setstate(is.failbit);
}
return is;
}
int main() {
// write to file
{
std::ofstream file("C:\\Users\\Amritesh\\Desktop\\student.txt");
person test1{10, "Foo Bar"};
person test2{20, "Apa Bepa"};
write(file, test1);
write(file, test2);
}
// read from file
{
std::ifstream file("C:\\Users\\Amritesh\\Desktop\\student.txt");
person test;
while(read(file, test)) {
std::cout << test.fname << '\n';
}
}
}
An example of making read and write member functions in person:
#include <iostream>
#include <string>
#include <fstream>
struct person {
int id;
std::string fname;
std::ostream& write(std::ostream& os) const {
// this does the same thing as in the first example
return os << id << ',' << fname << '\n';
}
std::istream& read(std::istream& is) {
if(is >> id && is.peek() == ',') {
is.ignore(); // step over the , char
std::getline(is, fname);
} else {
is.setstate(is.failbit); // we didn't get id or the , char
}
return is;
}
};
int main() {
// write to file
{
std::ofstream file("C:\\Users\\Amritesh\\Desktop\\student.txt");
person test1{10, "Foo Bar"};
person test2{20, "Apa Bepa"};
test1.write(file);
test2.write(file);
}
// read from file
{
std::ifstream file("C:\\Users\\Amritesh\\Desktop\\student.txt");
person test;
while(test.read(file)) {
std::cout << test.fname << '\n';
}
}
}
Member functions supported by stream operators:
#include <iostream>
#include <string>
#include <fstream>
struct person {
int id;
std::string fname;
std::ostream& write(std::ostream& os) const {
return os << id << ',' << fname << '\n';
}
std::istream& read(std::istream& is) {
if(is >> id && is.peek() == ',') {
is.ignore(); // step over the , char
std::getline(is, fname);
} else {
is.setstate(is.failbit); // we didn't get id or the , char
}
return is;
}
};
// stream operators calling member functions
std::ostream& operator<<(std::ostream& os, const person& p) { return p.write(os); }
std::istream& operator>>(std::istream& is, person& p) { return p.read(is); }
int main() {
// write to file
{
std::ofstream file("C:\\Users\\Amritesh\\Desktop\\student.txt");
person test1{10, "Foo Bar"};
person test2{20, "Apa Bepa"};
file << test1 << test2; // calling operator<< for each person object
}
// read from file
{
std::ifstream file("C:\\Users\\Amritesh\\Desktop\\student.txt");
person test;
while(file >> test) { // extract one person at a time using operator>>
std::cout << test.fname << '\n';
}
}
}

Reading from a struct from a binary file and inserting in a vector/STL::list and then returning it

I am reading a structure named "Highscore" from a binary file. I print the read data in the console and it looks fine. After that, I insert them into a vector with the push_back method and when I'm done, I return the vector.
After the return line, I get the following error (translated from French):
"Exception not handled at 0x00007FF6223FF017 in Project1.exe : 0xC0000005 : access violation while reading from 0xFFFFFFFFFFFFFFFF.".
Here is my code:
struct Highscore{
string username;
int points;
};
vector<Highscore> ReadFromHighscores(){
fstream highscoresFiles;
highscoresFiles.open("highscores.db", ios::in | ios::out | ios::binary | ios::app);
highscoresFiles.seekg(0);
Highscore output;
vector<Highscore> highscores;
highscoresFiles.read(reinterpret_cast<char *>(&output), sizeof(Highscore));
cout << "Read : " << output.points << output.username << endl;
Highscore temp;
temp.points = output.points;
temp.username = output.username;
if (!highscoresFiles.eof()) {
highscores.push_back(temp);
}
highscoresFiles.close();
return highscores;
}
As having been pointed out, std::string contains a char* (which you are saving and restoring) to the real data. The actual data is not saved and the pointer you restore is causing the crash. To fix that you can create operators for streaming to/from files and dump the username c-string (including the terminating \0) and then write the points int raw. This should work as long as your usernames don't contain \0 in the middle of the string (unusual but valid).
#include <iostream>
#include <iomanip>
#include <vector>
#include <fstream>
struct Highscore{
std::string username;
int points;
Highscore(const std::string& n, int p) : username(n), points(p) {}
Highscore() : Highscore("",0) {}
// operator to save a Highscore to file
friend std::ofstream& operator<<(std::ofstream&, const Highscore&);
// operator to read a Highscore from file
friend std::ifstream& operator>>(std::ifstream&, Highscore&);
// operator to print a Highscore on other ostreams (like std::cout)
friend std::ostream& operator<<(std::ostream&, const Highscore&);
};
std::ofstream& operator<<(std::ofstream& os, const Highscore& hs) {
os.write(hs.username.c_str(), hs.username.size()+1);
os.write(reinterpret_cast<const char*>(&hs.points), sizeof(hs.points));
return os;
}
std::ifstream& operator>>(std::ifstream& is, Highscore& hs) {
std::getline(is, hs.username, '\0');
is.read(reinterpret_cast<char*>(&hs.points), sizeof(hs.points));
return is;
}
std::ostream& operator<<(std::ostream& os, const Highscore& hs) {
os << std::setw(15) << std::left << hs.username << std::setw(8) << std::right << hs.points;
return os;
}
int main() {
// create "highscores.db"
{
std::vector<Highscore> highscores {
{"MadBrother33", 234234},
{"Barny", 14234},
{"Bart", 1434}
};
std::ofstream out("highscores.db", std::ios::binary);
for(auto& hs : highscores) {
out << hs;
}
}
// read "highscores.db"
{
std::vector<Highscore> highscores;
{
Highscore hs;
std::ifstream in("highscores.db", std::ios::binary);
while(in>>hs) {
highscores.emplace_back(std::move(hs));
}
}
for(auto& hs : highscores) {
std::cout << hs << "\n";
}
}
}
Output
MadBrother33 234234
Barny 14234
Bart 1434

C++ read line to class vector

I have next c++ class called "Contact":
class Contact
{
private:
std::string contactName;
double subscriptionPrice;
int minutesIncluded;
public:
Contact(const std::string &contactName, double subscriptionPrice,
int minutesIncluded) : contactName(contactName), subscriptionPrice(subscriptionPrice), minutesIncluded(minutesIncluded)) {}
Contact() {
}
...gettetrs and setters
}
I have text file with one or more contacts in format:
asd,1.00000,1
In main method I have method that add properly vector of contacts in this text file. Problem is when I try to read from it. My target is to convert text file into vector of contacts. Method I use is next:
void phonebook_load(vector<Contact> &contacts)
{
string line;
ifstream phonebook_file;
vector<std::string> lines;
phonebook_file.open(phonebook_filename);
if(!phonebook_file.is_open())
cout << "Phonebook file could not be openned !!!" << endl;
else
{
while (phonebook_file.good())
{
for (string line; getline(phonebook_file, line, ','); )
lines.push_back(line);
}
phonebook_file.close();
}
}
I have two options:
Read line by line (which I cannot split by ",")
Split by "," which print every property of contact on new line, and I don't see how tho handle it from there.
What should I change in my method in order to read file line by line and properly convert it to vector<Contact>
Provide stream extraction and stream insertion operators for your type:
#include <string>
#include <vector>
#include <iterator>
#include <fstream>
#include <iostream>
class Contact
{
private:
std::string contactName;
double subscriptionPrice;
int minutesIncluded;
public:
Contact() {}
Contact(const std::string &contactName, double subscriptionPrice, int minutesIncluded)
: contactName { contactName },
subscriptionPrice { subscriptionPrice },
minutesIncluded { minutesIncluded }
{}
// declare the stream extraction and stream insertion operators as firends
// of your class to give them direct access to members without the need for
// getter and setter functions.
friend std::istream& operator>>(std::istream &is, Contact &contact);
friend std::ostream& operator<<(std::ostream &os, Contact const &contact);
};
std::istream& operator>>(std::istream &is, Contact &contact)
{
std::string contact_name;
if (!std::getline(is, contact_name, ',')) // use getline with a delimiter
return is; // to allow whitespace in names
// which >> doesn't
char seperator;
double subscription_price;
int minutes_included;
if (!(is >> subscription_price >> seperator >> minutes_included) || seperator != ',') {
is.setstate(std::ios::failbit);
return is;
}
contact = Contact{ contact_name, subscription_price, minutes_included };
return is;
}
std::ostream& operator<<(std::ostream &os, Contact const &contact)
{
os << contact.contactName << ", " << std::fixed << contact.subscriptionPrice
<< ", " << contact.minutesIncluded;
return os;
}
int main()
{
std::ifstream is{ "test.txt" };
std::vector<Contact> contacts{ std::istream_iterator<Contact>{ is },
std::istream_iterator<Contact>{} };
for (auto const &c : contacts)
std::cout << c << '\n';
}

variable std::fstream file has initializer but incomplete type Compilation error

This is the file where the compiler shows where the error is. I have searched the same error online, most of them is caused by not including the< fstream >, but here I have included it, it still showing this error.
I forgot to add, in Visual Studio everything compiled with no problems, but when I uploaded it to my school matrix, it showed compilation error, and message is
"variable std::fstream file has initializer but incomplete type".
#include <iostream>
#include <fstream>
#include "MyFile.h"
using namespace std;
using namespace sict;
int main() {
fstream file("ms3.txt", ios::out);
file << "one" << endl << "two" << endl;
file.close();
MyFile F("ms3.txt");
F.load(file);
cout << "Linear: " << F << endl;
cout << "As is: " << endl;
F.print();
cout << "Enter the following: " << endl << "three<ENTER>" << endl << "four<ENTER>" << endl << "Ctrl-Z<ENTER>" << endl << endl;
cin >> F;
F.store(file, true);
F.load(file);
cout << F << endl;
F.print();
return 0;
}
This is my MyFile.h, and MyFile.cpp
#ifndef SICT_MYFILE_H__
#define SICT_MYFILE_H__
#include "Streamable.h"
#include "Streamable.h"
#include "Streamable.h" // Streamable.h is included three times on purpose.
namespace sict {
class MyFile : public Streamable {
char fname_[256];
char text_[10000];
public:
MyFile(const char* fname);
std::fstream& store(std::fstream& file, bool addNewLine)const;
std::fstream& load(std::fstream& file);
std::ostream& write(std::ostream& os, bool linear)const;
std::istream& read(std::istream& is);
void print();
};
std::ostream& operator<<(std::ostream& ostr, const MyFile& mf);
std::istream& operator >> (std::istream& istr, MyFile& mf);
}
#endif
MyFile.cpp
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
#include <cstring>
#include "MyFile.h"
using namespace std;
namespace sict {
MyFile::MyFile(const char* fname) {
text_[0] = char(0);
strcpy(fname_, fname);
}
fstream& MyFile::store(std::fstream& file, bool addNewLine)const {
file.open(fname_, ios::app | ios::out);
int i = 0;
while (text_[i]) {
file << text_[i];
i++;
}
file.close();
return file;
}
fstream& MyFile::load(std::fstream& file) {
file.open(fname_, ios::in);
int i = 0;
while (!file.fail()) {
text_[i++] = file.get();
}
file.clear();
file.close();
if (i > 0) i--;
text_[i] = 0;
return file;
}
ostream& MyFile::write(std::ostream& os, bool linear)const {
for (int i = 0; text_[i]; i++) {
if (linear && text_[i] == '\n') {
os << " ";
}
else {
os << text_[i];
}
}
return os;
}
istream& MyFile::read(std::istream& is) {
is.getline(text_, 9999, EOF);
return is;
}
void MyFile::print() {
write(cout, false);
cout << endl;
}
std::ostream& operator<<(std::ostream& ostr, const MyFile& mf) {
return mf.write(ostr, true);
}
std::istream& operator >> (std::istream& istr, MyFile& mf) {
return mf.read(istr);
}
}
The MyFile.h and MyFile.cpp were given, so I was not suppose to edit anything, I also added an interface for the 4 pure virtual functions in Streamable.h.
#ifndef SICT_STREAMABLE_H__
#define SICT_STREAMABLE_H__
namespace sict {
class Streamable {
public:
virtual std::fstream& store(std::fstream& file, bool addNewLine)const = 0;
virtual std::fstream& load(std::fstream& file) = 0;
virtual std::ostream& write(std::ostream& os, bool linear)const = 0;
virtual std::istream& read(std::istream& is) = 0;
};
}
#endif
This make no sense at all: #include "Streamable.h" // Streamable.h is included three times on purpose. In fact, it will do nothing except waste compilation time as you prevent multiple inclusions with #ifndef SICT_STREAMABLE_H__ anyway.
Also, a good habit is to always include the matched header file first (only after precompiled header file when it applies). That way, you know that header like MyFile.h has any necessary includes to compile for any source file (provided that you don't do weird things).
Thus MyFile.cpp should start with:
#include "MyFile.h"