C++ Why won't my sample program create the output file? - c++

I'm writing a small/beta testing program that will be put to use in my much bigger program for a project. It requests the user for an input file name (IE data.txt) and creates an output file named filename.out (IE data.out). I've tried a simple outFile << "text here"; to try it out but it doesn't create output file. I'm sure I'm messing something simple here but I can't figure out what.
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
//Global variables
ifstream inFile;
ofstream outFile;
void main()
{
// Requests user for input filename
string inputFile;
cout << "Enter File Name: ";
cin >> inputFile;
string outputFile = inputFile.substr(0, inputFile.find_last_of('.')) + ".out";
// Opens both inputFile and outputFile
inFile.open(inputFile.c_str(), ios::in);
outFile.open(outputFile.c_str(), ios::in);
// Checks for input file
if (!inFile)
{
cout << "Unable to open file" << endl;
exit(1);
}
outFile << "Hello world!";
inFile.close();
outFile.close();
}

Because you're trying to open the file for reading:
outFile.open(outputFile.c_str(), ios::in);
Use ios::out instead.

Why did you make these streams global variables rather than local ones? In C++, it's generally preferred to construct objects as late as possible. If you do this, you have all information available to open the streams right in the constructor, which can take the same arguments as the open() member function.
One difference between std::ifstream and std::ofstream is that their open() member functions and constructors apply a different default opening mode. It's in for std::ifstream and out for std::ofstream. You can always override these, but that would somewhat defeat the reason for using those streams in the first place. You could use std::fstream, too. For that you would always have to supply the opening modes. If you're using std::ifstream and std::ofstream, just skip the opening modes. Here's how this is looks when using the constructors instead of the open() member functions (it looks pretty much the same with the latter):
std::ifstream inFile(inputFile.c_str());
std::ofstream outFile(outputFile.c_str());
It's int main(), even if some compilers allow void.
I have strong objections to using directives. But these objections are not as widely shared as the other opinions listed in this answer.

Related

c++ : passing ofstream& to function to continually append to .txt file

I am writing a program for class wherein I need to call a function multiple times from "main.cpp" which takes an ofstream as a parameter, and the function itself needs to append new data to the end of the .txt file every time it's called (in this example I've made the data of type int for simplicity's sake).
What's been happening is that when the function gets called multiple times in main, it just overwrites everything instead of appending new data to the end of the file. I know everything else in my program works so I'm just going to strip it down to the bare bones as much as possible so that this isn't TL;DR. I have included
#include<fstream>
using namespace std;
in all of my files.
Here's the gist of it:
in main.cpp:
aClass* someClass = new aClass;
int data = 0;
...
ofstream myfile ("file.txt");
someClass->appendData(myfile, data);
...
in aClass.h:
void appendData(ofstream& myfile, int data);
in aClass.cpp:
void aClass::appendData(ofstream& myfile, int data){
if(myfile.is_open()){
myfile << data << "\n";
myfile.close();
}
else cout << "Couldn't open file";
}
If anyone could help me with this I'd appreciate it. For some reason they haven't had us touch fstreams in over a year and I'm not sure what the problem is here.
The call
myfile.close();
in appendData is not right. Any subsequent output operations on myfile are ignored.
Remove it from there.
You may add it in main but it is optional. The destructor will call close(). However, there is no harm if you call close() on the object if you are sure you are not going to use it to write into it any more

Template function returns wrong value while reading

I am trying to create class that reading and writing to the same file in c++ using template function and I'm trying to realize the function read() that reading a char or int and returns it and when i tried to run it i got number like -998324343 please help :)
#include<iostream>
#include<fstream>
using namespace std;
template <class T>
class myFile
{
ifstream in;
ofstream out;
public:
myFile(char* fileName)
{
in.open(fileName);
if (!in.is_open())
throw"couldnt open file to reading";
out.open(fileName);
if (!out.is_open())
throw"couldnt open file to writing";
cout << read();
}
T read() {
T x;
in >> x;
return x;
}
};
int main()
{
try {
myFile<int> a("read.txt");
}
catch (char* msg) {
cout << msg << endl;
}
}
Your out and in refer to the same file. So when this happens:
in.open(fileName);
if (!in.is_open())
throw"couldnt open file to reading";
out.open(fileName);
Assuming fileName exists as a file, out will truncate the file, so it becomes empty. The subsequent in >> x; will fail (because the file is empty) and depending on the C++ standard you're compiling against, either x will get zeroed out (since C++11) or remain unmodified (until C++11). I'm assuming you're compiling pre-C++11, in which case what you see is whatever indeterminate value x was initialized with.
Not sure what you need out for, but you either want it to refer to a different file or open it in append mode.
Regardless of whether or not out is truncating the file, the >> operation can fail. If it fails, you will get garbage data (or 0). So you need to check the result of that operation.
Note: Everywhere you are using char* you should be using const char*. The conversion from string literal to char* is deprecated (if you compiled with warnings enabled, you would see this).

Passing the current writing pointer of a file to a function in C++

suppose I want to write in a .txt file in following format
start-----
-----A----
----------
-B--------
-------end
I've 3 functions that write the parts to file; start to A, A to B then B to end.
My function call are going to be in this order
Func1(starts writing from start of file)
{ }
Func2(needs pointer to position A for writing to file)
{ }
Func3(needs pointer to position B for writing to file)
{ }
Take Fun1 and Func2 for example, Func1 will end writing at A, but the problem is that Func2 needs to go forward from point A. How can I pass a pointer of position A to Func2 so that it'll be able to continue writing from position A in the file?
Since this is c++ we could use file stream object from the standard c++ library.
#include <iostream>
#include <fstream>
using namespace std;
void func1(ofstream& f)
{
f << "data1";
}
void func2(ofstream& f)
{
f << "data2";
}
int main () {
ofstream myfile ("example.txt");
if (myfile.is_open())
{
func1(myfile);
func2(myfile);
myfile.close();
}
else cout << "Unable to open file";
return(0);
}
However this approach is universal. When you are working with file, you get some file identificator. It could be a FILE struct, Win32 HANDLE etc. Passing that object between functions will allow you to continuously write the file.
Not sure how you're outputting to a file (using which output method), but normally, the file pointer keeps track itself where it is up to.
eg using fstream
ofstream outFile;
outFile.open("foo.txt");
if (outFile.good())
{
outFile<<"This is line 1"<<endl
<<"This is line 2"; // Note no endl
outFile << "This is still line 2"<<endl;
}
If you pass the outFile ofstream object to a function, it should maintain position in the output file.
Previously answered: "ofstream" as function argument

Why can't I copy executables like this?

Using C++'s <fstream>, it's pretty easy to copy a text file:
#include <fstream>
int main() {
std::ifstream file("file.txt");
std::ofstream new_file("new_file.txt");
std::string contents;
// Store file contents in string:
std::getline(file, contents);
new_file << contents; // Write contents to file
return 0;
}
But when you do the same for an executable file, the output executable doesn't actually work. Maybe std::string doesn't support the encoding?
I was hoping that I could do something like the following, but the file object is a pointer and I'm not able to dereference it (running the following code creates new_file.exe which actually just contains the memory address of something):
std::ifstream file("file.exe");
std::ofstream new_file("new_file.exe");
new_file << file;
I would like to know how to do this because I think it would be essential in a LAN file-sharing application. I'm sure there are higher level APIs for sending files with sockets, but I want to know how such APIs actually work.
Can I extract, store, and write a file bit-by-bit, so there's no discrepancy between the input and output file? Thanks for your help, it's much appreciated.
Not sure why ildjarn made it a comment, but to make it an answer (if he posts an answer, I will delete this). Basically, you need to use unformatted reading and writing. getline formats the data.
int main()
{
std::ifstream in("file.exe", std::ios::binary);
std::ofstream out("new_file.exe", std::ios::binary);
out << in.rdbuf();
}
Technically, operator<< is for formatted data, except when use it like the above.
In very basic terms:
using namespace std;
int main() {
ifstream file("file.txt", ios::in | ios::binary );
ofstream new_file("new_file.txt", ios::out | ios::binary);
char c;
while( file.get(c) ) new_file.put(c);
return 0;
}
Although, you'd be better off making a char buffer and using ifstream::read / ofstream::write to read and write chunks at a time.

usage of ofstream

I'm kind of confused by ofstream.
ofstream inherited from ostream. And it
also inherited method "operator<<" from
ostream.
ofstream x;
x << "hello world" << endl;
//cout << "hello world" << endl;
system("pause");
return 0;
The above code clip is trying to use an object of ofsream
to output "hello world" to the terminal just as cout did.
The above code clip can compile but shows nothing.
Why does it happen?
Thanks,
ofstream is an abstraction for a file object. In order to be able to create a file, you need to pass in the file's name. If you don't a default ofstream object is created (which is why it compiles). By itself, such an object isn't of much use. Try:
ofstream x( "out.txt" );
x << "hello world" << endl;
...
It's been a long time, but IIRC of stream is an output_file-stream which streams data into an opened file. For an ofstream object to actually print to the terminal you would have to make it open "/dev/console" or something similar. A plain instance of ofstream probably doesnt open /dev/console b/c you already have cout available.
http://en.wikipedia.org/wiki/Input/output_%28C%2B%2B%29
<iostream> contains the definition of basic_iostream class template,
which implements formatted input and output
<fstream> contains the definitions of basic_ifstream, basic_ofstream and
basic_fstream class templates which implement formatted input, output and input/output
on file streams.