Simple encryption program runtime error

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
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.
Apart from what cire said
> scanf("%s", &text);
warning: format ‘%s’ expects argument of type ‘char*’, but argument 2 has type ‘char**’
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 :(

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;
}
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
because encrypted is not longer text. It contains arbitrary binary numbers even '\0'
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.
operator>>() only reads up to first white space (i.e. "My").
Use getline() instead.
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.