0

I was in needing of printing a Vigenere square inside a console window for a personal project but I'm experiencing some problems with the print function since it sneaks inside other classes' memory and prints out strings coming from them.

For those who don't know what is a Vigenere square, here's a picture

Here's my code:

static void square() {
    string cipher[27];
    cipher[0] = "  | A B C D E F G H I J K L M N O P Q R S T U V W X Y Z";
    for (int i = 0; i < 26; i++) {
        string tmp = (char)(i + 'A') + " |";
        for (int j = 0; j < 26; j++) {
            tmp += " " + (char)(((j + i) % 26) + 'A');
        }
        cipher[i + 1] = tmp;
    }
    for (int i = 0; i < 27; i++) cout << cipher[i] << endl;
}

My approach consists in creating each string one by one using a for cycle which incrememts the row's letter ascii value and another for for each of the coloumns shifted by 1. This is the weird output:

Console

I'm running this code alone but it steals the string "Invalid Option! Press any key to dismiss." from a class that I previously used to create the menu. I think it's someway how accessing parts of the memory reserved to that class. What am I doing Wrong?

Cristian
  • 654
  • 1
  • 13
  • 30
  • You haven't provided enough code to figure this out. – DeiDei Jan 10 '18 at 11:12
  • 2
    `(char)(i + 'A') + " |";` doesn't concatenate a char and a string literal. –  Jan 10 '18 at 11:22
  • 1
    This might interest you :<> quoted from here:https://stackoverflow.com/questions/17201590/c-convert-from-1-char-to-string . C++ is not that smart in contrast to VB.NET . It may seems rational to cast a char to string by adding an empty one before it (""+c) but it means something else. – sergiu reznicencu Jan 10 '18 at 11:23

3 Answers3

5

The problem is in those two lines:

string tmp = (char)(i + 'A') + " |";

    tmp += " " + (char)(j + i + 'A');

The right side of the assignment is evaluated first and only then is the result used to construct the std::string. A string literals are typically stored together in some static memory of the program. In the program the literal has value of a pointer pointing to that memory. A single character is basically a number. While the + plus operator is used for concatenating things with std::string, it behaves differently for pointers and numbers. If you add a char to char* pointer (or any pointer) it just points the pointer to a different place - in your case to some other string of the program.

To break it down:

  • (char)(i + 'A') + " |" assume i = 0 and " |" is stored e.g. on 0xabcd1234:
  • (char)(0 + 65) + (char*)0xabcd1234
  • (char)65 + (char*)0xabcd1234
  • (char*)0xabcd1275 - oops, we did not construct a concated string, we created pointer to some random memory!

There are many ways you could write the program. The smallest amount of changes would be this:

string tmp = (char)(i + 'A') + string(" |");

    tmp += string(" ") + (char)(j + i + 'A');

That means - make sure that at least one side of the + operator is actually std::string.

michalsrb
  • 4,703
  • 1
  • 18
  • 35
2

The main problem in your code is that you think that by concatenating an empty string with a char will automatically turn into a string ,which is wrong(it means "the pointer to some copy of an empty string, advanced by the numeric value of c (which is definitively not what you wanted); >> quoted from here:C++ convert from 1 char to string?).

The final code could look like this:

void square() {
    string cipher[27];
    cipher[0] = "  | A B C D E F G H I J K L M N O P Q R S T U V W X Y Z";
    for (int i = 0; i < 26; i++) {
        string tmp="";
        tmp+=(char)(i + 'A');
        tmp+=" |";
        for (int j = 0; j < 26; j++) {
            tmp += " ";
            tmp+=(char)(j + i + 'A');
        }
        cipher[i + 1] = tmp;
    }
    for (int i = 0; i < 27; i++) cout << cipher[i] << endl;
}

The chars are added to the string individually.

sergiu reznicencu
  • 1,039
  • 1
  • 11
  • 31
0

You are mixing string and char a lot which might not be your intention. Also I have assumed you are using std::string.

Instead of making an array of strings you should use a char array or a string.

Eg,

string cipher;
Jay
  • 636
  • 6
  • 19