tags:

views:

138

answers:

2

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();
}
+10  A: 

Because you're trying to open the file for reading:

outFile.open(outputFile.c_str(), ios::in);

Use ios::out instead.

AndiDog
Actually, this is the default for `std::ofstream::open()`, so `outFile.open(outputFile.c_str())` alone should do the job. Still you're correct, so `+1` from me.
sbi
+1 Check this page for a brief explanation of the openmodes: http://www.cplusplus.com/reference/iostream/ios_base/openmode/
karlphillip
Wow... thank you. I feel dumb now lol. Thanks karlphillip for that link also!
MOneAtt
+2  A: 
  1. 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.

  2. 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());
    
  3. It's int main(), even if some compilers allow void.

  4. I have strong objections to using directives. But these objections are not as widely shared as the other opinions listed in this answer.

sbi
+1 -- Corrections on #2: Actually, ifstream is missing all the output related member functions as well, i.e. operator<<, put, write, tellp, seekp and flush. ofstream misses input functions operator>>, gcount, get, getline, ignore, peek, read, readsome, putback, unget, tellg, seekg, and sync. Even if you override the open mode to use the wrong one for the given stream, you won't have the functions available to perform that respective I/O.
Billy ONeal
I made them Global so in my other program ( the bigger one i am currently working on ) the sub-programs (functions) can have access to write to outFile and read from inFile without passing outFile and inFile in the function parameters. If there is another way about this I don't currently know/ haven't learned about yet. But feel free to post a link to an article/ explain a better way. I'm always up for learning new things. Thanks!
MOneAtt
@Billy: Ah, I forgot about those. I'll edit my answer accordingly.
sbi
@MOneAtt: Global objects are bad. Passing local objects to functions is good, because you can see which function might or might not change them.
sbi
True...But at the moment it's less code to right and saves time by making the input and output global. And that's the only thing I ever make global. I'm sure once I advance in my learning in C++ I'll want to avoid doing such. Thanks !
MOneAtt