Am I on the right track?

The program is meant to read a .txt file a line at a time using getline.
Encrypt each character adding an encryption factor to the ASCII value and write the string to a second file.
The encoded file should have the same structure as the original file (if original file has 26 characters on the first line the encrypted will have 26 characters on the first line).

The encryption factor adds the number of the line to the ASCII value of each character, up to the 5th line then starts back at 1. (n-1)%5+1

I do not write in C++ well yet and figured I would start with adding a constant number first.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
 #include<iostream>
#include<string>
#include<fstream>

using namespace std;


int main()
{
	const int lineMax = numeric_limits<char>::max();
	const int new_line = '\n';
	const int encrypt = 1;

	ifstream inputFile("plain.txt");//Original file
	ofstream outputFile("encrypted.txt");//Encrypted file

	string input;

	cout << "Opening file...\n";
	system("pause");
	if (!inputFile)
		cout << "Error opening plain.txt.\n";
		
	cout << "Encrypting file..\n";
	system("pause");


	if (inputFile)
	{
		string input;
		while (getline(inputFile, input))
		{
			for (char c : input)
			{
				char new_character = c + encrypt;

				if (new_character < lineMax && new_character != new_line) 
				{
					c = new_character;
				}
				else
				{
					cout << "Error";
				}
			}
			outputFile << input << '\n';
		}
	}
	return 0;
}
Consider:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <string>
#include <fstream>

int main()
{
	std::ifstream inputFile("plain.txt");		//Original file
	std::ofstream outputFile("encrypted.txt");	//Encrypted file

	std::cout << "Opening files...\n";

	if (!inputFile || !outputFile)
		return (std::cout << "Error opening files\n"), 1;

	std::cout << "Encrypting file..\n";

	size_t lineno {};

	for (std::string input; std::getline(inputFile, input); ++lineno) {
		for (char& c : input)
			c += 1 + lineno % 5;

		outputFile << input << '\n';
	}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <string>
#include <fstream>
using namespace std;

string operator + ( string str, int n )
{
   for ( char &c : str ) c += n;
   return str;
}

int main()
{
   ifstream in( "plain.txt" );
   ofstream out( "encrypted.txt" );
   string line;
   for ( int n = 0; getline( in, line ); n++ ) out << line + ( n % 5 + 1 ) << '\n';
}

Yep, that's definitely what I would expect string + int to do.
What is the benefit, if any to using or not using namespace std;?
What is the benefit, if any to using or not using namespace std;?


You could Google that, plenty written about it.
What is the benefit, if any to using or not using namespace std;?


Well, it stops the key with a ':' on your keyboard getting worn down ...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <string>
#include <fstream>

std::string operator + ( std::string str, int n )
{
   for ( char &c : str ) c += n;
   return str;
}

int main()
{
   std::ifstream in( "plain.txt" );
   std::ofstream out( "encrypted.txt" );
   std::string line;
   for ( int n = 0; std::getline( in, line ); n++ ) out << line + ( n % 5 + 1 ) << '\n';
}
I could also imagine that the std namespace is pretty expansive so would you recommend using it while still learning all the symbols in the library?
I guess what I'm trying to figure out is, is it okay to use starting out? Or should I absolutely avoid it at all costs so as to not develop any bad habits?
Last edited on
So I got the encryption code down, now I want to write a decryption code.
This encrypts only the first line though,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include <string>
#include <fstream>
using namespace std;

string operator - (string str, int n)
{
	for (char& c : str) c += n;
	return str;
}

int main()
{
	cout << "Opening file..\n";
	system("pause");

	ofstream outputFile("plain.txt");
	ifstream inputFile("encrypted.txt");
	if (!inputFile || !outputFile)
		cout << "File error.\n";

	if(inputFile)
	cout << "Encrypting file..\n";
	system("pause");

	string input;

	for (int n = 0; getline(inputFile, input); n++)
		outputFile << input - (n % 5 - 1) << '\n';

	cout << "File encrypted successfully.\n";
	system("pause");
	return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <string>
#include <fstream>

std::string& operator%(std::string& str, uint8_t n)
{
	for (char& c : str)
		c += n;

	return str;
}

int main()
{
	std::cout << "Opening file..\n";

	std::ofstream outputFile("plain.txt");
	std::ifstream inputFile("encrypted.txt");

	if (!inputFile || !outputFile)
		return (std::cout << "File error.\n"), 1;

	std::cout << "Encrypting file..\n";

	std::string input;

	for (size_t n = 0; getline(inputFile, input); ++n)
		outputFile << input % (n % 5 + 1) << '\n';

	std::cout << "File encrypted successfully.\n";
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <string>
#include <fstream>
using namespace std;

string operator + ( string str, int n )
{
   for ( char &c : str ) c += n;
   return str;
}

string crypt( const string &line, int n ){ return line + n; }

int main()
{
   string line;
   ifstream in( "plain.txt" );
   ofstream out( "encrypted.txt" );
   for ( int n = 0; getline( in, line ); n++ ) out << crypt( line, n % 5 + 1 ) << '\n';
   in.close(); out.close();
   
   in.open( "encrypted.txt" );
   out.open( "decrypted.txt" );
   for ( int n = 0; getline( in, line ); n++ ) out << crypt( line, -(n % 5 + 1) ) << '\n';
   in.close(); out.close();   
}
Last edited on
In this instance, I don't like overloading operator+. + usually means addition or concatenation. I used % above which is not ideal but IMO is better than + in this context.

What operator would others use in this context?

Well, my logic is that:
'c' + n will work for a single char;
A string is an array of chars
string + n is just an array operation (I'm used to languages doing precisely that).


But
%
is a modular division, which, if anything here, means "break up".


The closest operator here would probably be >>, but that would play havoc with input/output.


You could always use a function directly, and call it "shift".


Or you can just avoid the pedantry:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <string>
#include <fstream>
using namespace std;

string crypt( string str, int n )
{
   for ( char &c : str ) c += n;
   return str;
}

int main()
{
   string line;
   ifstream in( "plain.txt" );
   ofstream out( "encrypted.txt" );
   for ( int n = 0; getline( in, line ); n++ ) out << crypt( line, n % 5 + 1 ) << '\n';
   in.close(); out.close();
   
   in.open( "encrypted.txt" );
   out.open( "decrypted.txt" );
   for ( int n = 0; getline( in, line ); n++ ) out << crypt( line, -(n % 5 + 1) ) << '\n';
   in.close(); out.close();   
}
Last edited on
Why overload the operator at all? It could clash with somebody else's overload, couldn't it? Wouldn't it be better to just use a regular function?
(I'm asking.. not suggesting)
Our posts (and my edit) crossed, @chirumer.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <string>
#include <fstream>

enum Enc_t :int8_t { DECRYPT = -1, ENCRYPT = 1 };

std::string& crypt(std::string& str, uint8_t n, Enc_t typ)
{
	for (char& c : str)
		c += n * typ;

	return str;
}

int main()
{
	std::ifstream in("plain.txt");
	std::ofstream out("encrypted.txt");

	if (!in || !out)
		return (std::cout << "Cannot open files\n"), 1;

	std::string line;

	for (size_t n = 0; getline(in, line); ++n)
		out << crypt(line, n % 5 + 1, ENCRYPT) << '\n';

	in.close();
	out.close();

	in.open("encrypted.txt");
	out.open("decrypted.txt");

	if (!in || !out)
		return (std::cout << "Cannot open files\n"), 2;

	for (size_t n = 0; getline(in, line); ++n)
		out << crypt(line, n % 5 + 1, DECRYPT) << '\n';
}

Topic archived. No new replies allowed.