Simple encryption program runtime error

Jul 22, 2014 at 3:15pm
I am trying to make a simple program for encrypting a char* with the XOR operator.
The code compiles and links perfectly, but I get an Access violation runtime error:

Unhandled exception at 0x1000435C (msvcr120d.dll) in encrypt.exe: 0xC0000005: Access violation reading location 0x0000794D.


This is my code:

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 <cstdlib>
#include <cstdio>
#include <string>
#include <fstream>

using namespace std;

int main(int argc, char** argv)
{
	if (argc < 2)
	{
		cout << "Error: First command line argument must be the output filename." << endl;
		return -1;
	}

	char* text = new char;
	char key[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
	char* encrypted = new char;

	printf("Enter the text to be encrypted: \n");

	int x = 0;
	scanf("%s", &text);

	for (int i = 0; i < strlen(text); i++) // This line causes the error
	{
		encrypted[i] = text[i] ^ key[x];
		if (x++>7) // Key is and 8 element array, so we need another counter to prevent array index out of bounds exception
		{
			x = 0;
		}
	}

	FILE* file = fopen(argv[1], "w");
	fprintf(file, "%s", encrypted);  //write to file

	return 0;
}


Text that I am inputting:

My username is memberfunction.


What went wrong?

Thanks in advance.


Last edited on Jul 22, 2014 at 4:03pm
Jul 22, 2014 at 3:34pm
line 29 should be: if (++x > 7)

Line 17 allocates a single character.
Line 19 allocates a single character.

That means the only valid C-style string you can store is an empty one.

NOTE: I am using scanf and the other functions from the C library because I am inputting a C-style string.


No. You're using C-style input and output because you're using C-style input and output. It doesn't have anything at all to do with the specifics of the string representation.
Jul 22, 2014 at 3:52pm
Apart from what cire said
> scanf("%s", &text);
warning: format ‘%s’ expects argument of type ‘char*’, but argument 2 has type ‘char**’
Jul 22, 2014 at 5:01pm
Thank you very much! It works! Do you know how to do this with std::string and the other C++ awesomeness?

I am asking because I am not good at C :(

Jul 22, 2014 at 5:17pm
Do you know how to do this with std::string and the other C++ awesomeness?

Here's one way you might do it:
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
#include <iostream>
#include <fstream>
#include <string>
#include <array>

int main(int argc, char** argv)
{
    if (argc < 2)
    {
        std::cout << "Error: First command line argument must be the output filename.\n";
        return -1;
    }

    const std::array<char, 8> key = { 1, 2, 3, 4, 5, 6, 7, 8 };

    std::string text;
    std::cout << "Enter the text to be encrypted:\n> ";
    std::cin >> text;

    std::string encrypted;
    unsigned key_index = 0;

    for (auto ch : text)
        encrypted += ch ^ key[key_index++ % key.size()];

    std::ofstream out(argv[1]);
    out << encrypted;
}
Jul 31, 2014 at 10:50am
Ok, now this is weird.

Everything compiles and links perfectly, but when I enter My username is memberfunction. in the program, the output is
L{
I tried to change the key, but I'm always getting two letters. Everything is correct.
What went wrong?
Last edited on Jul 31, 2014 at 10:51am
Jul 31, 2014 at 11:09am
because encrypted is not longer text. It contains arbitrary binary numbers even '\0'
Jul 31, 2014 at 3:11pm
But why doesn't this happen when I use C-style strings? When I use C-style strings, the encrypted string is long as the plain text.
Jul 31, 2014 at 3:46pm
operator>>() only reads up to first white space (i.e. "My").
Use getline() instead.
Jul 31, 2014 at 5:17pm
Thank you very much!

I have no idea how I forgot this!
Now I am getting some (very easy to break) weird text.
Topic archived. No new replies allowed.