Logan Logan - 1 month ago 10
C++ Question

How can I fix this to where the function will print out the results of the key_shift change into the output file?

The problem lies within the encrypt function, and probably...elsewhere.
I am unable to get the output text file to update with any text.
I know if I use the shift key added this way it will eventually mess up on certain letters so I need to also find a way to make sure z is taken care of. But right now I just want the text to end up on the output file.

#include <iostream>
#include <cstdlib>
#include <fstream>

using namespace std;

void display_menu(); //Display the menu
void get_files(ifstream& in_stream, ofstream& out_stream);
void encrypt(ifstream &in_stream, ofstream &out_stream, int key_shift); //Encrypts a file
int get_num_1_through_10(int number); //Gets an integer numbered 1-10 and has the user re-enter integer if incorrrect

int main()
{
ifstream in_stream; //declaring the input file path
ofstream out_stream; //delcaring the output file path
string in_filename, out_filename;

int option; //Declaration of user "option" choice
int key_shift; //Declaration of user "shift key value" choice
do //Runs menu at least once
{
display_menu(); //function call
cin >> option; //User inout for the option menu
switch (option)
{

case 1:
cout << "Enter a value between 1 and 10 for the shift key value: "; //Prompts the user to choose a "shift key value" between integers 1-10
cin >> key_shift; //User input for the "shift key value"

get_num_1_through_10(key_shift); //Function call to get a number 1-10

cout << "You have chosen a shift key value of " << key_shift << endl; //Prints to screen users "shift key value" choice
break;

case 2:
cout << "Time to get the files set up!\n";

cout << "Beginning the encryption process...\n";

encrypt(in_stream, out_stream, key_shift);

in_stream.close();
out_stream.close();

break;

case 3:
break;

case 4:
cout << "Goodbye" << endl; //User chooses to quit the program
return 0;

default:
cout << "Enter a choice 1-4" << endl; //Alerts the user of incorrect input
}

} while (option != 4); //While option is anything other than 1-4, quits
return 0; //Quits
}

void display_menu()
{
cout << "1) Set the shift key value" << endl;
cout << "2) Encrypt a message" << endl;
cout << "3) Decrypt a message" << endl;
cout << "4) Quit" << endl;
cout << "Type in an option and hit enter: ";
}

int get_num_1_through_10(int number)
{

if ((number > 0) && (number < 11))
{ //Excluding integers except integers 1-10

return number; //If true, returns the users integer choice
}

else
{ //If false, returns user back to menu function
cout << "Please input a number between 1 and 10\n"; //Reminds the user of incorrect integer input
return main(); //Returns to main function
}
}

void encrypt(ifstream &in_stream, ofstream &out_stream, int key_shift)
{

ifstream in_filename;
ofstream out_filename;
get_files(in_filename, out_filename);

char ch;

in_stream.get(ch);

while (!in_stream.eof())
{

while (ch != '\n')
{
ch = ch + key_shift;
out_stream << ch;
}
}
return;
}

void get_files(ifstream& in_stream, ofstream& out_stream)
{

string in_filename, out_filename;
cout << "Enter the source file name: ";
cin >> in_filename; //User types in the file name to receive data
cout << "Enter the destination file name: ";
cin >> out_filename; //User types in the file name to out the data to

in_stream.open(in_filename.c_str()); //Opens the stream for input file
out_stream.open(out_filename.c_str()); //Opens the stream for out file

if (in_stream.fail() || out_stream.fail())
{ //If the input or output fail
cout << "Error opening input/output files\n"; //Alerts the user of failure
return; //Terminates
}
}

Answer

Problem 1:

while (!in_stream.eof()) 

Will read past the end of the file and provide one extra reading before it tests that it's heat the end of the file. More here: Why is iostream::eof inside a loop condition considered wrong?

Solution:

Read, then test for a valid read (and not just for EOF because many things can go wrong), and then, if the read is valid, use the value read.

Problem 2:

in_stream.get(ch);
while (!in_stream.eof()) {
    while (ch != '\n') {
        ch = ch + key_shift; 
    out_stream << ch;
    }
}

Nowhere in this loop is ch read. If the value is not read it wont change and you can be pretty sure the EOF is never going to be read.

Solution:

Read ch in the loop.

Something like

while (in_stream.get(ch)) {

    while (ch != '\n') {
        ch = ch + key_shift; 
        out_stream << ch;
    }
}

Should kill both stones with one bird. while (in_stream.get(ch)) reads and then tests, only entering the body of the loop if the read is successful.

Comments