ofstream doesn't open, or write to files - c++

I've been looking at this for hours and I just know the answer is simple. It seems no matter what I do I cannot open a file. It's a multi-class program so in the header I have
#include <iostream>
#include < fstream>
class A{
string path;
A(string p): path(p){}
...
...
void PrintToFile();
void PrintBase();
void PrintNext();
...
...
};
and in the cpp file I have
#include "A.h"
void A::PrintToFile(){
ofstream f(path.c_str(), ios::out);
assert(f.is_open);
f << "markuptext" << endl;
PrintBase();
f << "endtag" << endl;
f.close();
}
void A::PrintBase(){
ofstream f(path.c_str(), ios::app);
assert(f.is_open);
f << "markuptext" << endl;
f << somevale << endl;
PrintNext();
f << "endtag" << endl;
f.close()
}
void A::PrintNext(){
ofstream f (path.c_str(), ios::app);
assert(f.is_open);
f << "markuptext" << endl;
f << somevalue << endl;
f << "endtag" << endl;
f.close()
}
I've played around with the flags on the constructors and with the open commands as well. And once it managed to open a file, but it never wrote anything to the file. If you have any insights I'd much appreciate it.
edit
Thanks for all the help guys, looks like I was trying to open a file with "". But even now after I've got that straightened out, my code is not writing to that open file. I checked my permissions and I'm doing chmod a+rwx... well here's the code in more detail.
#ifndef XML_WRITER_H
#define XML_WRITER_H
#include "WordIndex.h"
#include "PageIndex.h"
#include "StringUtil.h"
#include "CS240Exception.h"
#include <iostream>
#include <fstream>
/* prints out the wordIndex to an xml file
*/
class XMLWriter{
private:
WordIndex * wIndex;
PageIndex * pIndex;
URL baseurl;
//const char * file;
ofstream f;
public:
XMLWriter();
XMLWriter(string base);
XMLWriter(XMLWriter & other){
assert(&other != NULL);
Init(other);
}
XMLWriter & operator =(XMLWriter & other){
Free();
Init(other);
}
~XMLWriter(){
Free();
}
void Load(WordIndex & wi, PageIndex & pi);
//prints to the file
void Print(char * ofile);
private:
void Init(XMLWriter & other){
baseurl = other.baseurl;
wIndex = other.wIndex;
pIndex = other.pIndex;
}
void Free(){
}
void PrintWebsite();
void PrintStartURL();
void PrintPages();
void PrintIndex();
void PrintWord(OccurenceSet ocs);
void PrintValue(string s);
void PrintOccurence(Occurence o);
void PrintPage(Page & page );
void PrintDescription(string dscrptn );
void PrintValue(int n );
void PrintURL(URL url );
};
#endif
.cpp file
#include "XMLWriter.h"
XMLWriter::XMLWriter(){
}
XMLWriter::XMLWriter( string base): baseurl(base){
//cout << "filename : " << filename << endl;
//file = filename.c_str();
//cout << "file : " << *file << endl;
}
void XMLWriter::Load(WordIndex & wi, PageIndex & pi){
wIndex = &wi;
pIndex = π
wIndex->ResetIterator();
pIndex->ResetIterator();
}
void XMLWriter::Print(char * filename){
cout << filename << endl;
ofstream f(filename);
if(!f){
cout << "file : " << filename;
throw CS240Exception("could not open the file for writing");
}
PrintWebsite();
f.close();
}
//private methods
//
void XMLWriter::PrintWebsite(){
f <<"<website>\n";
PrintStartURL();
PrintPages();
PrintIndex();
f << "</website>" << endl;
}
// startURL
//
void XMLWriter::PrintStartURL( ){
f << "\t" << "<start-url>"<< endl;
string val = baseurl.Value();
StringUtil::EncodeToXml(val);
f << "\t\t" << val << endl;
f << "\t" << "</start-url>"<< endl;
}
//pages
//
void XMLWriter::PrintPages(){
f << "\t" << "<pages>"<< "\n";
while(pIndex->HasNext())
PrintPage(*(pIndex->Next()));
f << "\t" <<"</pages>"<< '\n';
}
void XMLWriter::PrintPage(Page & page ){
f << "\t\t" <<"<page>"<< endl;
PrintURL(page.Value());
PrintDescription(page.Description() );
f << "\t\t" <<"</page>"<< endl;
}
void XMLWriter::PrintURL(URL url){
f << "\t\t\t<url>"<< endl;
f << "\t\t\t\t" << StringUtil::EncodeToXmlCopy(url.Value()) << endl;
f << "\t\t\t</url>"<< endl;
}
void XMLWriter::PrintDescription(string dscrptn){
f << "\t\t\t<description>";
f << StringUtil::EncodeToXmlCopy(dscrptn);
f << "</description>"<< endl;
}
//index
//
void XMLWriter::PrintIndex(){
f << "\t<index>"<< endl;
while(wIndex->HasNext())
PrintWord(*(wIndex->Next()) );
f << "\t</index>"<< endl;
}
void XMLWriter::PrintWord(OccurenceSet ocs ){
f << "\t\t<word>" << endl;
PrintValue(ocs.Value());
ocs.ResetIterator();
while(ocs.HasNext())
PrintOccurence(*(ocs.Next()) );
f << "\t\t</word>"<< endl;
}
void XMLWriter::PrintValue(string s ){
f << "\t\t\t<value>";
f << StringUtil::EncodeToXmlCopy(s);
f << "</value>"<< endl;
}
void XMLWriter::PrintOccurence(Occurence o ){
f << "\t\t\t<occurence>" << endl;
PrintURL(o.Value()->Value());
PrintValue(o.NumOfOccur());
f << "<\t\t\t/occurence>"<< endl;
}
void XMLWriter::PrintValue(int n ){
f << "\t\t\t\t<count>";
f << n;
f << "</count>"<< endl;
}
it won't write anything to the file :( but now it is creating a file so thats a step :-D.
obviously I have a data structures and other things backing this up, but I just need to get it writing. Thanks in advance

The most obvious problem is that you are opening the file several times.
Each instance of the open file will have its own file position and its
own buffer. In addition, depending on the system, either all open's but
the first will fail (Windows, I think), or the open will truncate the
file, effectively erasing any information that might have been written
to it. What you should do is have PrintToFile pass the open stream to
the functions it calls (recursively); each of these functions should
take a std::ostream& (not std::ofstream&) to receive it.

One thing I see is that you are opening the file several times. Maybe that would cause trouble. You open it first in PrintToFile then while it is still open there you open it for append in PrintBase. Then while in PrintBase you open it yet again in the call to PrintNext.
Put the ofstream as a member of the class, open it once and refer to it from all three functions.

I would use a simple if :
ofstream f (path.c_str(), ios::app);
if(!f)
{
throw std::exception(std::string("Could not open file : " + path + "for writing"));
}
//write to file here
f.close();
This way you can be sure if the file was opened succesfully or not.

Related

How are you supposed to use set_rdbuf()?

So I am creating a class that inherits from ifstream, and that gives me acces to the protected function set_rdbuf, and at first I just thought it allowed you to set your own filebuf that then would be used, but that does not seem to work for me. I wrote the following code:
class A : public std::fstream {
private:
std::filebuf m_file_buf;
public:
A() {
if (!m_file_buf.open("test_file.txt", ios_base::out | ios_base::in)) {
std::cout << "something went wrong";
}
// std::fstream::rdbuf()->swap(m_file_buf);
std::fstream::set_rdbuf(&m_file_buf);
std::cout << "m_ file buff is: " << m_file_buf.is_open() << "\n";
std::cout << "rd file buff is: " << std::fstream::rdbuf()->is_open() << "\n";
std::cout << "we are: " << std::fstream::is_open() << "\n";
}
};
int main() {
A a;
return 0;
}
This will log:
m_ file buff is: 1
rd file buff is: 0
we are: 0
I was under the assumption that when I called rdbuf() I would then get the one I had set it to. However, if I use the swap function that rdbuf() provides, then it prints as I expect it to
class A : public std::fstream {
private:
std::filebuf* m_file_buf;
public:
A() {
m_file_buf = new std::filebuf();
if (!m_file_buf->open("test_file.txt", ios_base::out | ios_base::in)) {
std::cout << "something went wrong";
}
std::fstream::rdbuf()->swap(*m_file_buf);
std::cout << "m_ file buff is: " << m_file_buf->is_open() << "\n";
std::cout << "rd file buff is: " << std::fstream::rdbuf()->is_open() << "\n";
std::cout << "we are: " << std::fstream::is_open() << "\n";
// Get it back again as we swapped it out
m_file_buf = std::fstream::rdbuf();
}
};
int main() {
A a;
return 0;
}
m_ file buff is: 0
rd file buff is: 1
we are: 1
//and when I at the end swap back, everything is 1/open
I swited to pointer in the swap code so that I could point to the return of rdbuf()
This was compiled on MSVC version 19.28 with arg /std:c++17
So am I wrong is how set_rdbuf is supposed to be used, or is there something else I am doing wrong?

Output from file using function

the title says it all
This is my code:
I have a class called House, where i define the values.
class HOUSE
{
public:
int id;
string 1;
string 2;
string 3;
int an;
};
template<class Type>
class table
{
public:
vector<Type> V;
//double inceput;
//double sfirsit;
//int comparatii;
//int interschimbari;
public:
table();
void print();
void liniar();
};
template<class Type>
table<Type>::table()
{
ifstream file("file.txt");
ifstream file1("file1.txt");
if (file.fail() || file1.fail())
{
cerr << "Eroare la deschiderea fisierului!" << endl;
_getch();
exit(1);
}
HOUSE* value = new HOUSE;
while (!file.eof() || file1.fail())
{
file >> value->id;
file >> value->tara;
file >> value->brand;
file >> value->culoare;
file >> value->an;
this->V.push_back(*value);
}
file.close();
}
The print function for the values
template<class Type>
void table<Type>::print()
{
cout << endl << setw(50) << "AFISAREA DATELOR" << endl;
cout << setw(5) << "Id" << setw(15) << "1" << setw(20) << "2" << setw(17) << "3" << setw(20) << "an" << endl << endl;
for (int i = 0; i < this->V.size(); i++)
{
cout << setw(5) << this->V.at(i).id << setw(15)
<< this->V.at(i).1<< setw(17)
<< this->V.at(i).2<< setw(17)
<< this->V.at(i).3<< setw(25)
<< this->V.at(i).an << endl;
}
cout << endl << "Dimensiunea tabelului n= " << V.size() << endl;
}
{
file >> value->id;
file >> value->1;
file >> value->2;
file >> value->3;
file >> value->an;
this->V.push_back(*value);
}
file.close();
}
in main
int main() {
table<MOBILE>* file = new table<MOBILE>();
table<MOBILE>* file1 = new table<MOBILE>();
file ->print();
file1 ->print();
This is full code as requested.
Need make it somehow print the data from file1 and file2 .
thx
The problem is idk if called right. Because
file ->print();
file1 ->print();
both print data from the file only
There are no errors at all
There's lots and lots wrong with your code. but I'm going to ignore that and just answer what I think is your actual question.
You want two table objects, one of which reads from file.txt and the other reads from file1.txt. To do that you should pass the file name into the table::table constructor, so it knows which file to read from. Like this
template<class Type>
class table
{
...
public:
table(const char* filename); // constructor takes filename parameter
...
};
template<class Type>
table<Type>::table(const char* filename)
{
ifstream file(filename); // open filename
if (file.fail())
...
int main() {
table<MOBILE>* file = new table<MOBILE>("file.txt"); // read from file.txt
table<MOBILE>* file1 = new table<MOBILE>("file1.txt"); // read from file1.txt
file ->print();
file1 ->print();
}

C++ ofstream only outputting last line of data from ifstream

I am trying to read from a file and output data to a separate file. Only problem is that when I run the program the output on the file is from the data on the last line of the input file. I also don't want to append the output file since I don't want the data to duplicate when I rerun the program which is why i'm not using ios::app in the output.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
//class declaration
class call_record{
public:
string cell_number;
int relays;
int call_length;
double net_cost;
double tax_rate;
double call_tax;
double total_cost;
};
//Prototypes
void input(ifstream & in, call_record &);
void process(call_record &);
void output(call_record &);
//Input function
void input(ifstream & in, call_record & customer_record){
in >> customer_record.cell_number >> customer_record.relays >>
customer_record.call_length;
}
//Process function
void process(call_record & customer_record){
if(customer_record.relays >= 0 && customer_record.relays <=5){
customer_record.tax_rate = 0.01;
} else if(customer_record.relays >= 6 && customer_record.relays <=11){
customer_record.tax_rate = 0.03;
} else if(customer_record.relays >= 12 && customer_record.relays <=20){
customer_record.tax_rate = 0.05;
} else if(customer_record.relays >= 21 && customer_record.relays <=50){
customer_record.tax_rate = 0.12;
}
//net cost of call
customer_record.net_cost = (customer_record.relays/50 * 0.40 *
customer_record.call_length);
//cost of tax on call
customer_record.call_tax = customer_record.net_cost *
customer_record.tax_rate;
//Total cost of call
customer_record.total_cost = customer_record.net_cost +
customer_record.call_tax;
}
void output(call_record & customer_record){
ofstream out("weekly_call_info.txt");
out.setf(ios::showpoint);
out.precision(2);
out.setf(ios::fixed);
out << customer_record.cell_number << " " << customer_record.relays << " "
<< customer_record.call_length << " " << customer_record.net_cost << " "
<< customer_record.tax_rate << " " << customer_record.call_tax << " " <<
customer_record.total_cost << endl;
out.close();
}
int main(){
call_record customer_record;
ifstream in("call_data.txt");
if(in.fail()){
cout << "Your input file does not exist or did not open properly." <<
endl;
} else {
while (!in.eof()){
input(in, customer_record);
process(customer_record);
output(customer_record);
}
}
in.close();
return 0;
}
This is different than the other posts because I am using both an input stream and an output stream in 2 separate functions and I don't think I fully understand how to implement them correctly in my main function.
The problem is that you are always creating weekly_call_info.txt each time output() is called and truncating the existing file. This is because you are not specifying the std::ios_base::app ("append") open mode flag, so the existing content of weekly_call_info.txt is lost. See this page for a helpful table that shows the equivalent C-style mode strings for the different combinations of open mode flags: http://en.cppreference.com/w/cpp/io/basic_filebuf/open
I suggest passing a reference to the std::ostream to which you want to output data to the output() function:
void output(call_record & customer_record, std::ostream& out){
out << customer_record.cell_number << " " << customer_record.relays << " "
<< customer_record.call_length << " " << customer_record.net_cost << " "
<< customer_record.tax_rate << " " << customer_record.call_tax << " " <<
customer_record.total_cost << endl;
}
int main(){
call_record customer_record;
ifstream in("call_data.txt");
if(in.fail()){
cout << "Your input file does not exist or did not open properly." << endl;
} else {
ofstream out("weekly_call_info.txt");
out.setf(ios::showpoint);
out.precision(2);
out.setf(ios::fixed);
for (;;) {
input(in, customer_record);
if (!in) break;
process(customer_record);
output(customer_record, out);
}
}
return 0;
}
If you really do want to open weekly_call_info.txt for writing multiple times, you will want to use the std::ios_base::app open mode flag to append to the existing file. See appending to a file with ofstream.

Writing .csv files from C++

I'm trying to output some data to a .csv file and it is outputting it to the file but it isn't separating the data into different columns and seems to be outputting the data incorrectly.
ofstream Morison_File ("linear_wave_loading.csv"); //Opening file to print info to
Morison_File << "Time Force(N/m)" << endl; //Headings for file
for (t = 0; t <= 20; t++) {
u = sin(omega * t);
du = cos(omega * t);
F = (0.5 * rho * C_d * D * u * fabs(u)) + rho * Area * C_m * du;
cout << "t = " << t << "\t\tF = " << F << endl;
Morison_File << t; //Printing to file
Morison_File << F;
}
Morison_File.close();
Time and Force(N/m) are in columns A and B respectively but the t and F values are both printing the first row.
What is the syntax to separate them to print t into column A and F into column B?
There is nothing special about a CSV file. You can create them using a text editor by simply following the basic rules. The RFC 4180 (tools.ietf.org/html/rfc4180) accepted separator is the comma ',' not the semi-colon ';'. Programs like MS Excel expect a comma as a separator.
There are some programs that treat the comma as a decimal and the semi-colon as a separator, but these are technically outside of the "accepted" standard for CSV formatted files.
So, when creating a CSV you create your filestream and add your lines like so:
#include <iostream>
#include <fstream>
int main( int argc, char* argv[] )
{
std::ofstream myfile;
myfile.open ("example.csv");
myfile << "This is the first cell in the first column.\n";
myfile << "a,b,c,\n";
myfile << "c,s,v,\n";
myfile << "1,2,3.456\n";
myfile << "semi;colon";
myfile.close();
return 0;
}
This will result in a CSV file that looks like this when opened in MS Excel:
Here is a STL-like class
File "csvfile.h"
#pragma once
#include <iostream>
#include <fstream>
class csvfile;
inline static csvfile& endrow(csvfile& file);
inline static csvfile& flush(csvfile& file);
class csvfile
{
std::ofstream fs_;
const std::string separator_;
public:
csvfile(const std::string filename, const std::string separator = ";")
: fs_()
, separator_(separator)
{
fs_.exceptions(std::ios::failbit | std::ios::badbit);
fs_.open(filename);
}
~csvfile()
{
flush();
fs_.close();
}
void flush()
{
fs_.flush();
}
void endrow()
{
fs_ << std::endl;
}
csvfile& operator << ( csvfile& (* val)(csvfile&))
{
return val(*this);
}
csvfile& operator << (const char * val)
{
fs_ << '"' << val << '"' << separator_;
return *this;
}
csvfile& operator << (const std::string & val)
{
fs_ << '"' << val << '"' << separator_;
return *this;
}
template<typename T>
csvfile& operator << (const T& val)
{
fs_ << val << separator_;
return *this;
}
};
inline static csvfile& endrow(csvfile& file)
{
file.endrow();
return file;
}
inline static csvfile& flush(csvfile& file)
{
file.flush();
return file;
}
File "main.cpp"
#include "csvfile.h"
int main()
{
try
{
csvfile csv("MyTable.csv"); // throws exceptions!
// Header
csv << "X" << "VALUE" << endrow;
// Data
csv << 1 << "String value" << endrow;
csv << 2 << 123 << endrow;
csv << 3 << 1.f << endrow;
csv << 4 << 1.2 << endrow;
}
catch (const std::exception& ex)
{
std::cout << "Exception was thrown: " << e.what() << std::endl;
}
return 0;
}
Latest version here
Change
Morison_File << t; //Printing to file
Morison_File << F;
To
Morison_File << t << ";" << F << endl; //Printing to file
a , would also do instead of ;
You must ";" separator, CSV => Comma Separator Value
ofstream Morison_File ("linear_wave_loading.csv"); //Opening file to print info to
Morison_File << "'Time'; 'Force(N/m)' " << endl; //Headings for file
for (t = 0; t <= 20; t++) {
u = sin(omega * t);
du = cos(omega * t);
F = (0.5 * rho * C_d * D * u * fabs(u)) + rho * Area * C_m * du;
cout << "t = " << t << "\t\tF = " << F << endl;
Morison_File << t << ";" << F;
}
Morison_File.close();
If you wirte to a .csv file in C++ - you should use the syntax of :
myfile <<" %s; %s; %d", string1, string2, double1 <<endl;
This will write the three variables (string 1&2 and double1) into separate columns and leave an empty row below them. In excel the ; means the new row, so if you want to just take a new row - you can alos write a simple ";" before writing your new data into the file. If you don't want to have an empty row below - you should delete the endl and use the:
myfile.open("result.csv", std::ios::out | std::ios::app);
syntax when opening the .csv file (example the result.csv). In this way next time you write something into your result.csv file - it will write it into a new row directly below the last one - so you can easily manage a for cycle if you would like to.
As explained above by #kris, depending on the region configurations of MS Excel it won't interpret the comma as the separator character. In my case I had to change it to semi-colon

c++ ofstream keeps failing member function

I have made a program, where I want to write some things on a file. When I do it directly from my main-function it works fine, but when i make this class member function, it fails to do that. std::cout works without a problem, and I don't receive any error message. It just doesn't write on the file. This is my code:
#include <fstream>
... // not relevant
template <class T>
void Grid <T>::write() const {
int printcount = 0;
ofstream outputFile;
outputFile.open("data.txt", ios::app);
for (vector<T>::const_iterator iter = matrix.begin(); iter != matrix.end(); ++iter) {
++printcount;
cout << setw(12) << *iter;
outputFile << setw(12) << *iter;
if (printcount % Columns == 0) {
cout << endl;
outputFile << endl;
}
}
cout << endl;
outputFile << endl;
outputFile.close();
}