views:

403

answers:

2

This is in reference to another question I asked, though it is its own question entirely.

when I compile I get two errors:

1>.\asst4.cpp(73) : error C2065: 'outfile' : undeclared identifier

1>.\asst4.cpp(73) : error C2228: left of '.close' must have class/struct/union

I'm slightly confused as to what I've done incorrectly here? Any reccomendations or ideas? (The actual outfile is near the top of the code.

Here is the full code:

#include<iostream>
#include<fstream>  //used for reading/writing to files.
#include<string>    //needed for the filename.
#include<stdio.h>   //for goto statement

using namespace std;

int main()
{
    string start;
    char choice;
    char letter;
    int x;
    int y;
    int z;
    string filename;
    int garbage = rand()%('!' - '~' + 1 );
    cout << "Would you like to encrypt or decrypt a file? Please type enc, dec, or stop (case sensitive): " ;
    cin >> start;
    while(start == "enc")
    {
     x = 1;
     y = 1;
     cout << "How many garbage characters would you like between each correct character?: " ;
     cin >> z;
     cout << endl << "Please insert the name of the document you wish to encrypt, make sure you enter the name, and the file type (ie: filename.txt): " ;
     cin >> filename;
     ifstream infile(filename.c_str());
     while(!infile.eof())
     {
      ofstream outfile("encrypted.txt", ios::out);
      infile.get(letter); 
      if (x == y)         
       {
       outfile << garbage;
       x++;             
      }
      else
      {
       if((x - y) == z)   
       {
        outfile << letter;   
        y = x;     
       }
       else      
       {       
        outfile << garbage;
        x++;
       }
      }
     }
     cout << endl << "Encryption complete...please return to directory of program, a new file named encrypted.txt will be there." << endl;
     infile.close();
     outfile.close();
     cout << "Do you wish to try again? Please press y then enter if yes (case sensitive).";
     cin >> choice;
     if(choice == 'y')
     {
      start = "enc";
     }
     else
     {
      cout << endl << "Do you wish to decrypt a file? Please press y then enter if yes (case sensitive).";
      if(choice = 'y')
      {
       start == "dec";
      }
      else
      {
       start == "no";
      }
     }
    }
    while(start == "dec")
    {

      //lets user choose whether to do another document or not.
      //used to track each character in the document.
     x = 1;    //first counter for tracking correct letter.
     y = 1;   //second counter (1 is used instead of 0 for ease of reading, 1 being the "first character").
        //third counter (used as a check to see if the first two counters are equal).
     //allows for user to input the filename they wish to use.
     cout << "Please make sure the document is in the same file as the program, thank you!" << endl << "Please input document name: " ;
     cin >> filename; //getline(cin, filename); 
     cout << endl;
     cout << "'Every nth character is good', what number is n?: ";
     cin >> z;   //user inputs the number at which the character is good. IE: every 5th character is good, they would input 5.
     cout << endl;
     z = z - 1;  //by subtracting 1, you now have the number of characters you will be skipping, the one after those is the letter you want.
     ifstream infile(filename.c_str()); //gets the filename provided, see below for incorrect input.
     if(infile.is_open()) //checks to see if the file is opened.
     {
      while(!infile.eof())    //continues looping until the end of the file.
      { 
        infile.get(letter);  //gets the letters in the order that that they are in the file.
        if (x == y)          //checks to see if the counters match...
        {
         x++;             //...if they do, adds 1 to the x counter.
        }
        else
        {
         if((x - y) == z)   //for every nth character that is good, x - y = nth - 1.
         {
          cout << letter;   //...if they don't, that means that character is one you want, so it prints that character.
          y = x;     //sets both counters equal to restart the process of counting.
         }
         else      //only used when more than every other letter is garbage, continues adding 1 to the first
         {       //counter until the first and second counters are equal.
          x++;
         }
        }
      }
      cout << endl << "Decryption complete...please return to directory of program, a new file named encrypted.txt will be there." << endl;
      infile.close();
      cout << "Do you wish to try again? Please press y then enter if yes (case sensitive).";
      cin >> choice;
      if(choice == 'y')
      {
       start == "dec";
      }
      else
       {
       cout << endl << "Do you wish to encrypt a file? Please press y then enter if yes (case sensitive).";
       if(choice == 'y')
       {
        start == "enc";
       }
       else
       {
        start == "no";
       }
      }
     }
     else  //this prints out and program is skipped in case an incorrect file name is used.
     {
      cout << "Unable to open file, please make sure the filename is correct and that you typed in the extension" << endl;
      cout << "IE:" << "     filename.txt" << endl;
      cout << "You input: " << filename << endl;
      cout << "Do you wish to try again? Please press y then enter if yes (case senstive)." ;
      cin >> choice;
      if(choice == 'y')
      {
       start == "dec";
      }
      else
      {
       start == "no";
      }
     }
     getchar();  //because I use visual C++ express.
    }
}

Thanks ahead of time! Jeff

+3  A: 

Scoping issue. You are declaring outfile within your while loop, yet are trying to access it outside of said while loop.

Move ofstream outfile("encrypted.txt", ios::out); to the line right after your ifstream infile(filename.c_str()); which is before your while(!infile.eof()).

X-Istence
that did it, now there's an actual flaw in the logic I have, somewhere it's deciding to not print to the file...and a moment ago while running it, when I stopped it because it seemed to have frozen and opened the txt file, I actually managed to get notepad to crash, point for me!
Jeff
And as always, thank you for the assistance!
Jeff
A: 

You've got two choices - as X-istence mentions, the reason your call to outfile.close() is not compiled is because the object 'outfile' does not exist in the same scope as the declaration of outfile.

You could either move the line


ofstream outfile("encrypted.txt", ios::out);

outside the while loop so it obeys the same scoping rules as infile, or you can move your call to outfile.close(); inside the while loop, which would move it into the current scope in which outfile exists.

My preference would be to move the declaration of outfile outside the while loop as opening a file is quite an expensive operation and you really don't want to do this for every letter you read from infile. Open it once, close it once is the way to go in this case.

Timo Geusch