ofstream creates a file but can't write to it

Bryan Smith picture Bryan Smith · Feb 7, 2012 · Viewed 13.1k times · Source

REVISED: Here is my entire compilable program. It is menu driven, but the part that I am stuck on is option DECRYPT, to decrypt a caesar cyphered file, or number 5 (either could be typed in at the initial question, the decrypt could be lower case, upper case, or camel case). The ofstream variable outFile creates a file named by the user (must be a non-existing file). The problem is that it only creates the empty file, and does not print any of the data into it. All of the variables store the correct values. cout works, but outFile does not. Is there something that I am not doing correctly? I have tried to test for bad, fail, and is_open and none of them have any trouble. I do not think that file permissions would prevent anything either, since the other options in the program create and write to a file just fine. Can anyone help me?

#include <iostream>
#include <fstream>
#include <string>
#include <cctype>
#include <map>
#include <iomanip>
#include <vector>
using namespace std;
int main() {
string inputFileName, outputFileName, inData, outData, inWord, outWord, trash;
ifstream inFile, testStream;
ofstream outFile;
bool outPutOpened = false, isLowerCase = false;
char outChar, inChar; 
int shiftNum = 0, idx = 0, total = 0, max = 0, shiftValue = 0;
map<char,int> charMap; 
map<char,int>::iterator mapIt; 
vector<char> alphabet(26); 
vector<char>::iterator shiftIt;
do  {
    inWord.clear();
    outWord.clear();
    cout << "Available options: " << endl;
    cout << "1. ENCRYPT - Encrypt a file using Caesar Cypher" << endl
        << "2. CHARFREQ - display character frequency table for file" 
        << endl << "3. Quit - Exit the program" << endl 
    << "5. DECRYPT - decrypt a cyphered file" << endl << endl;
    cout << "   Enter keyword or option index: ";
    getline(cin, inWord);
    outWord.resize(inWord.length());
    transform(inWord.begin(), inWord.end(), outWord.begin(), ::toupper); 
    if (outWord.compare("ENCRYPT") == 0 || outWord.compare("1") == 0) {
        cout << "CAESAR CYPHER PROGRAM" << endl
        << "======================" << endl << endl;
        do {                
            cout << "Provide the input file name: ";

            getline(cin, inputFileName);

            inFile.open(inputFileName.c_str());
            if (inFile.fail()) {
                cout << "Cannot open file, please try again!" << endl;
                inFile.clear();
            }
        }
        while (!inFile.is_open());

        do {
            cout << "Provide the output file name: ";
            cin >> outputFileName;
            getline(cin, trash);                
            testStream.clear();
            testStream.open(outputFileName.c_str());
            if(testStream.good()) {
                cout << "That file already exists, choose another" << endl;
                testStream.clear();
                testStream.close();
            }
            else {
                testStream.clear();
                testStream.close();
                outFile.open(outputFileName.c_str());
                if (outFile.good()) {
                    outPutOpened = true;
                }   
            }
        }
        while (!outPutOpened); 
        cout << "Enter the shift number: ";
        cin >> shiftNum;
        getline(cin, trash );
        while(getline(inFile, inData)) {

        for (idx = 0; idx <= inData.length() - 1; idx++) {
            if  (inData[idx] >= 'a' && inData[idx] <= 'z') {
                outChar = (((inData[idx] - 'a') + shiftNum) % 26) + 'a';
                outFile.put(outChar);
            }
            else if (inData[idx] >= 'A' && inData[idx] <= 'Z'){
                outChar = (((inData[idx] - 'A') + shiftNum) % 26) + 'A'; 
                outFile.put(outChar);
            }
            else {
                outFile.put(inData[idx]);
            }
        }
        }
        inFile.clear();
        inFile.close();
        outFile.clear();
        outFile.close();
    }
    else if (outWord.compare("2") == 0 || outWord.compare("CHARFREQ") == 0){
        cout << "Enter input file name: ";
        getline(cin, inputFileName);
        inFile.open(inputFileName.c_str());
        while (inFile.get(inChar)) {
            if (charMap.find(inChar) == charMap.end()) {
                charMap[inChar] = 1 ;
            }
            else {
                ++charMap[inChar];
            }
        }
        cout << "Character Frequencies For \"" << inputFileName << "\"" 
            << endl;
        for (mapIt = charMap.begin(); mapIt != charMap.end(); mapIt++) {
            total += (*mapIt).second;
        }
        cout << "Total bytes read: " << total << endl;
        for (mapIt = charMap.begin(); mapIt != charMap.end(); mapIt++) {
            cout << " ('" << (*mapIt).first << "') occurs " 
            << (*mapIt).second << " times (" 
            << static_cast<double> ((*mapIt).second) 
            / static_cast<double> (total) << "% of all characters)" << endl;
        }
        inFile.clear();
        inFile.close();
    }
    else if (outWord.compare("5") == 0|| outWord.compare("DECRYPT") == 0) {
        outPutOpened = false;
        do {                
            cout << "Provide the input file name: ";

            getline(cin, inputFileName);

            inFile.open(inputFileName.c_str());
            if (inFile.fail()) {
                cout << "Cannot open file, please try again!" << endl;
                inFile.clear();
            }
        }
        while (!inFile.is_open());          
        while (inFile.get(inChar)) {
            if (inChar < 'a' || inChar > 'z') {
                inFile.ignore();
            }
            else {
                inChar -= 'a'; 
                alphabet[static_cast<int> (inChar)]++;
            }
        }
        for (idx = 0; idx < alphabet.size(); idx++) {
            if(max < alphabet[idx]){
                max = alphabet[idx];
            }
        }
        shiftIt = find(alphabet.begin(), alphabet.end(), max);

        shiftValue = (distance(alphabet.begin(), shiftIt) - 4);
        if (shiftValue < 0) {
            shiftValue += 26;
        }
        inFile.close();
        do {                
            inFile.open(inputFileName.c_str());
            if (inFile.fail()) {
                cout << "Cannot open file, please try again!" << endl;
                inFile.clear();
            }
        }
        while (!inFile.is_open());

        outPutOpened = false;
        do {
            cout << "Provide the output file name: ";
            cin >> outputFileName;
            getline(cin, trash);                
            testStream.clear();
            testStream.open(outputFileName.c_str());
            if(testStream.good()) {
                cout << "That file already exists, choose another" << endl;
                testStream.clear();
                testStream.close();
            }
            else {
                testStream.clear();
                testStream.close();
                outFile.open(outputFileName.c_str());
                if (!outFile.good()) {
                    cout << "bad output"<< endl;
                    outFile.clear();
                }   
                if (outFile.good()) {
                    outPutOpened = true;
                }
            }
        }
        while(!outPutOpened); 

        while((inFile.get(inChar))) {

            if  (inChar >= 'a' && inChar <= 'z') {


                inChar -= shiftValue;
                if (inChar < 'a') {
                    inChar += 26;
                }

            outFile << inChar;
            }
            else if (inChar >= 'A' && inChar <= 'Z'){
                inChar -= shiftValue;
                if (inChar < 'A') {
                    inChar += 26;
                }
                outFile << inChar;   

            }
            else {
                outFile << inChar;
            }

        }
    }
    else if (outWord.compare("3") == 0 || outWord.compare("QUIT") == 0) {
        break;
    }
    else {
        cout << inWord << " is an unrecognized option, please try again" 
        << endl;
    }
}
while (outWord.compare("3") || outWord.compare("QUIT")); 
return 0;

}

Answer

Default picture Default · Feb 8, 2012

you have to flush the stream in order for the chars to actually be written to file. after your write-to-outFile-while loop do a:

outFile.flush();

.. and the text will be written fine to the file.