Encrypting program using C-strings

Hi!
I'm trying to write a program that encrypts a user-entered message using two C-strings, one is a regular alphabet, and the other is a special one.

So what I'm trying to do with this block of code is concatenate codesquare, first with codeword, and then alpha. But, I don't want repeated letters in codesquare, so I'm trying to concatenate it with alpha minus the letters that are in codeword.

My issue is that when I try to compile it, I get an error that says "
No matching function for call to strcat()
." It also says "
Note: no known conversion from char to const char * for 2nd argument
." I can't figure it out and would gladly appreciate any advice.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
char codesquare[26];
char alpha[27] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

char codeword[8] = "OPENING";

strncat (codesquare, codeword, 7);

for (int count = 0; count < sizeof (codeword); count++)
{
	for (int index = 0; index < sizeof (alpha); index++)
	{
		if (codeword[count] != alpha[index])
		{
			strcat (codesquare, alpha[index]);
		}
		else
		{
			continue;
		}
	}
}

My os is Mac OS X Sierra, and-don't beat me up for this please-I am not using an IDE, instead I am using Macromates' TextMate application to write and edit code, and Apple's Terminal.app to compile and run.
Last edited on
If you're using strcat, make sure you have #include <cstring> in your file.

alpha is a char array, so alpha[index] is an individual char.
But strcat's signature is: char * strcat ( char * destination, const char * source );

It expects a pointer to null-terminated char array as the second argument (the source is concatenated onto the destination).

One way to make it see a single character as a null-terminated char array would be something like:

1
2
char cat[2] { alpha[index], '\0' };
strcat(codesquare, cat);
Last edited on
Ah, I think I see now. So it won't accept a single char as the second argument?

Hmm. When I try to compile it now, it gives me this error:
error: expected ';' at end of declaration
char cat[2] { alpha[index], '\0' };
           ^
           ;

Shouldn't there be a = between the [2] and the opening bracket?

Edit:
Apparently not. My C++ textbook says that in order to assign a value to a c-string, you need to use strcpy(), and the second argument needs to be another c-string or a string literal.
Edit 2:
Okay, so I (hehe) tried adding the & operator in front of alpha[index], like so:
strcat (codesquare, &alpha[index]);
And that gave me a Segmentation Fault: 11 error! *google search* That apparently means that it was accessing memory that it wasn't supposed to. Erp.
Last edited on
Right, doing &alpha[index] is getting a pointer, but it will attempt to append the entire alpha array, which is going to go out of bounds of the destination array.

The = is optional for array initialization. Maybe it was necessary before C++11, if you're using an old compiler.

You also need to make sure the destination is correctly null-terminated to begin with.
i.e. codesquare[0] = '\0'; or char codesquare[26] {};

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Example program
#include <iostream>
#include <cstring>

int main()
{
    char codesquare[26] {};
    char alpha[27] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    
    strcat(codesquare, "Letter: ");
    
    char letter[2] {alpha[5], '\0'}; // Letter: F
    strcat(codesquare, letter);
    
    std::cout << codesquare << '\n';
}


If that doesn't compile for you, try
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Example program
#include <iostream>
#include <cstring>

int main()
{
    char codesquare[26];
    codesquare[0] = '\0';
    
    char alpha[27] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    
    strcat(codesquare, "Letter: ");
    
    char letter[2] = {alpha[5], '\0'}; // Letter: F
    strcat(codesquare, letter);
    
    std::cout << codesquare << '\n';
}
The second one worked! Thanks!

Edit:
I inserted part of your program into mine, and it gave me the segmentation fault 11 again, but I think the problem is with my loops–I think they're running for too long or something.
Edit 2:
I finally decided to debug it, and guess what? I figured out that the inner loop is actually iterating once for each iteration of the outer loop! So it's actually trying to concatenate codesquare with alpha 8 times! Which isn't going to work! Well, back to the drawing board.

And thanks again, @Ganado for your help!
Last edited on
Well, your continue statement on line 18 is effectively a no-op because it's the last instruction in the block, so perhaps there's some unintentional logic or lack thereof there.

Also, note that sizeof(null-terminated char array) will give a length one more than strlen(null-terminated char array) because of the null terminator.

If you're having trouble, you can post your current code and be specific about what issues you're having.
Last edited on
Ah! Thank you, I did not notice that! I will correct it to strlen(), and that should solve at least part of it. Here is my current code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
char codesquare[26];
char alpha[27] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

char codeword[8] = "OPENING";

strncat (codesquare, codeword, 7);

for (int count = 0; count < strlen (codeword); count++)
{
	for (int index = 0; index < strlen (alpha); index++)
	{
		if (codeword[count] != alpha[index])
		{
			char letter[2] = {alpha[index], '\0'};
			strcat (codesquare, letter);
		}
		else
		{
			continue;
		}
	}
}


I think what it's doing is it's iterating the inner loop 8 times, once for each iteration of the outer loop. So I'll have to change the counter variable in the outer one.
Last edited on
Update:
So, I tried switching the for loops so the outer one is now the inner one, and vice versa:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
for (int index = 0; index < strlen (alpha); index++)
{
	for (int count = 0; count < strlen (codeword); count++)
	{
		if (codeword[count] != alpha[index])
		{
			char letter[2] = {alpha[index], '\0'};
			strcat (codesquare, letter);
		}
		else
		{
			continue;
		}
	}
}
puts (codesquare);
puts (alpha);

And...now the output is
OPENINGAAAAAAABBBBBBBCCCCCCCDDDDDDDEEEEEEFFFFFFFGGGGGGHHHHHHHIIIIIIJJJJJJJKKKKKKKLLLLLLLMMMMMMM
NNNNNOOOOOOPPPPPPQQQQQQQRRRRRRRSSSSSSSTTTTTTTUUUUUUUVVVVVVVWWWWWWWXXXXXXXYYYYYYYZZZZZZZ
ABCDEFGHIJKLMNOPQRSTUVWXYZ

Progress! Now all I need to do is figure out some way to get rid of the extra letters...
make codeword [100] in size to see if it helps. This looks suspiciously like a char array blowout.
codesquare as well.
initialize them to ALL zeros, use sprintf or strcat or something to set the real initial value.
so
char codeword[100]{};
sprintf(codeword, "OPENING");
Last edited on
Well...ok, expanding the sizes of codeword and codesquare to 100 does this:
 ????OPENINGAAAAAAABBBBBBBCCCCCCCDDDDDDDEEFFFFFFFGGGGGGHHHHHHHIIIIJJJJJJJKKKKKKKLLLLLLLMMMMMMMNNN
PQQQQQQQRRRRRRRSSSSSSSTTTTTTTUUUUUUUVVVVVVVWWWWWWWXXXXXXXYYYYYYYZZZZZZZ

Initialize them to all zeros, is there a shorter way to do it, other than just a lot of copying and pasting like this?
1
2
char codeword[100] = {'0', '0', '0', ... '\0'};
//With the "..." meaning a whole bunch more '0's 
yes.
char codeword[100]{}; // {} is zero, null, empty, etc zero-for-the-type and it will fill all the locations.

if you didn't have that, a for loop or memcpy or the like can be used, but there isnt any need for crude tools here.

I am trying to help you find the issue, this may not even work. If zero initialized and larger arrays does something different, then you know to look for something that is off by one or otherwise accidentally wiping out one of the terminating zeros in one of your strings.

what is the expected output, anyway..?
Last edited on
Well, this is supposed to be a sort of encryption program, and the codesquare c-string is supposed to be sort of a template for replacing the letters in the message with different letters.
What I was intending was for the "codesquare" c-string to contain
 
char codesquare[27] = "OPENINGABCDFHJKLMQRSTUVWXYZ";

So, it is supposed to contain the word "OPENING, and the letters of the alphabet (except the letters in "OPENING").
Then I can use it as sort of a template , along with the "alpha" c-string to replace the letters in a user-entered message with other letters, based on the template.
Hope that made sense.
ok. and what did you get after zero initializing?
Do you mean this:

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

int main()
{
	const char alpha[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	const char const codeword[] = "OPENING";

	char codesquare[sizeof(alpha)] = {};

	auto dest = strcat(codesquare, codeword) + strlen(codeword);

	for (auto al = alpha; *al; ++al)
		if (strchr(codeword, *al) == NULL)
				*dest++ = *al;

	std::cout << codesquare << '\n';
}



OPENINGABCDFHJKLMQRSTUVWXYZ

Last edited on
@jonnin
After initializing to zeros, the output was still

OPENINGAAAAAAABBBBBBBCCCCCCCDDDDDDDEEFFFFFFFGGGGGGHHHHHHHIIIIJJJJJJJKKKKKKKLLLLLLLMMMMMMMNNNP
QQQQQQQRRRRRRRSSSSSSSTTTTTTTUUUUUUUVVVVVVVWWWWWWWXXXXXXXYYYYYYYZZZZZZZ

@seeplus
Yes that was the output I was looking for, thanks very much! I didn't think of doing it that way, but it makes sense! Guess I didn't even need those nested loops, oh well. Live and learn, my dad always said. Thanks, Ganado, jonnin, seeplus!
Topic archived. No new replies allowed.