views:

249

answers:

3

Not as in "can't find the answer on stackoverflow", but as in "can't see what I'm doing wrong", big difference!

Anywho, the code is attached below. What it does is fairly basic, it takes in a user created text file, and spits out one that has been encrypted. In this case, the user tells it how many junk characters to put between each real character. (IE: if I wanted to encrypt the word "Hello" with 1 junk character, it would look like "9H(eal~l.o")

My problem is that for some reason, it isn't reading the input file correctly. I'm using the same setup to read in the file as I had done previously on decrypting, yet this time it's reading garbage characters, and when I tell it to output to file, it prints it on the screen instead, and it seems like nothing is being put in the output file (though it is being created, so that means I've done something correctly, point for me!

code:

string start;
char choice;
char letter;
int x;
int y;
int z;
char c;
string filename;

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());
 ofstream outfile("encrypted.txt", ios::out);

 while(!infile.eof())
 {
  infile.get(letter); 
  while ((x - y) != z)         
  {
   outfile << putchar(33 + rand() % 94);
   x++;    
  }
  while((x - y) == z)
  {
   outfile << letter;
   y = 1;
   x = 1;
  }
 }
 outfile.close();
 cout << endl << "Encryption 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;

What I pasted above the start of the while loop are the declaration variables, this is part of a much larger code that not only will encrypt, but decrypt as well, I left the decryption part out as it works perfectly, it's this part I'm having an issue with.

Thanks in advance for the assist!

EDIT:: I'm using visual C++ express 2008, and it shoots back that there are no errors at all, nor any warnings.

IMPORTANT EDIT It turns out it is outputting to the file! However, it is outputting numbers instead of ascii characters, and it is also outputting the garbage character for the letter it should be. When it goes back to the "infile.get(letter)", it doesn't get a new character. So right now it seems to be the issues are 2 fold: 1) Printing numbers instead of ascii characters. 2) Using garbage instead of the actual character it should be getting.

Question Answered Found out the second part in the "Important Edit" ...it turns out if you name something test.txt...that means it is actually called test.txt.txt when you type it into a C++ program. Just goes to show it's the tiny, minute, simple details that cause any program to go pooey. Thank you to George Shore. Your comment about the input file being in the wrong place is what gave me the idea to try the actual items name.

Thank you to everyone who helped with the answer!

A: 

Is the use of 'y' necessary? It seems confusing and unnecessary to me. If I were implementing this, then I'd expect to use just 'x' and 'z'.

I'm also not sure about the 'while (!infile.eof())' condition; Pascal determines EOF ahead of time, but C++ can only tell you about EOF after attempting to read a character. However, this would only affect the end of the file, not the main body of the loop.

    while (!infile.eof())
    {
        infile.get(letter);
        if (infile.good())
        {
            for (int i = 0; i < z; i++)        
                outfile << putchar(33 + rand() % 94);
            outfile << letter;
        }
    }

(Uncompiled code!).

Also, do not use this for security - it may help a little, but it certainly won't conceal the information from the determined.

Jonathan Leffler
Couldn't find any other way to determine how if I should place the actual character, or the garbage character, but it makes sense to me and that was what mattered. My issue though is with the infile not reading and the outfile not writing, thanks for your input though :) Always appreciated!
Jeff
Is my first C++ class, as far as I've been taught (and I've read), it's needed to do all the statements until the file has ended.
Jeff
indeed it wouldn't, is being used for a homework assignment not due till the end of the quarter (8 weeks away or so), but I find coding enjoyable and wanted to do it now, just couldn't figure out the issue. So how does this output to the file and what I wrote not?
Jeff
In short, I'm looking for the reason it doesn't work, not just a "this works"! Thanks though, I will poke around with that code and see what happens
Jeff
while I'll probably change out my x, y, z for your for loop, as that makes sense now that I'm looking at it, the rest of the code doesn't work. the infile.get(letter); is still pulling garbage, not the characters in the file, when I ran it this time it gave a copyright symbol for letter, weird.
Jeff
+3  A: 

Rather than doing this:

while (!infile.eof())
{
    infile.get(letter);
    if (infile.good())
    {

Do this:

while (infile.get(letter))
{

This is the standard pattern for reading a file.
It gets a character and the resulting infile (that is returned by get) is then checked to see if it is still good by converting it to bool.

The line:

outfile << putchar(33 + rand() % 94);

Should probably be:

outfile << static_cast<char>(33 + rant() % 94);

putchar() prints to the standard output. But the return value (same as the input) goes to the outfile. To stop this just convert the value to char and send to outfile.

Martin York
Doing that skips over that entire while loop and does nothing...how is that supposed to work?
Jeff
I thought there had to be a slicker way to do that testing! Note that the questioner is adamant that he needs to know what is wrong with his code.
Jonathan Leffler
Jeff: If the while loop skips then that means the infile is bad. Since this would be the first read this probably suggests that the file was not found.
Martin York
+4  A: 

Further to the previous answers, I believe it's because the file you wish to encrypt is not being found by the original code. Is it safe to assume that you're running the code from the IDE? If so, then the file that is to be encrypted has to be in the same directory as the source.

Also:

outfile << putchar(33 + rand() % 94);

seems to be the source of your garbage to the screen; the 'putchar' function echoes to the screen whilst returning the integer value of that character. What is then going to happen is that number will be output to the file, as opposed to the character.

Changing that block to something like:

while ((x - y) != z)         
{
    c = (33 + rand() % 94);
    outfile << c;
    x++;
}

should enable the code to run as you want it to.

George Shore
(Doing this one part at a time so as to not confuse myself or others) I put the 'test.txt' file in the same directory as the source, I actually made a copy of it I encrypted by hand and saved it into the same file, and tested it with the decryption part of the code, so it is in the correct spot.
Jeff
attempted code as you posted, it is indeed no longer printing the numbers, but now it's printing those block symbols I usually see when the computer can't read a character. I assume I should keep 'c' as a char? Just to be sure I'm understanding.
Jeff
Indeed, 'c' should still be a char. Is the text file you're using a plain ASCII-encoded file, or in UTF8 or similar? All the tests I've done with your code verbatim work correctly, which is now confusing me...
George Shore
Cancel that I think, seems to be outputting the ascii characters just fine...guess it was a hiccup of some kind I overlooked.
Jeff
It's just a plain, simple, right-click create new .txt document. Probably something I pressed on my end, but that code works perfectly now! Now if I can just get it to read the input file, I'll be golden! ..well..perhaps a bit tarnished, but still golden!
Jeff
A quick check to see if the file has been found/opened is to add: if(!infile.is_open()) break;replacing the 'break' statement as required for what to do when the file is not found. Hope this helps too.
George Shore
Helped a lot! I edited the actual question as I can write more there than here, turned out not to be a code error, but a naming error, one of the many downfalls of human users I suppose.
Jeff