It's ok when I use uppercase letters, but I get random stuff when I use lower case letters

#include <iostream>
#include <conio.h>

using namespace std;

string sentence, key;
int todo, koef, keylenth, senlenth;

int main()
{

    cout<<"Do not use spaces!"<<endl<<endl;



     cout<<endl<<endl<<"Key:  ";                    //enter the key
    cin>>key;                                       

    keylenth = key.length();                                                       
    char *keymas = new char[keylenth];                                                       
    key.copy(keymas, keylenth, 0);                 



    cout<<endl<<"Enter the message:              ";
    cin>>sentence;
    cout<<endl<<endl<<"Сiphered message:      ";

    senlenth = sentence.length();                                                 
    char *massentence = new char[senlenth];
    sentence.copy(massentence, senlenth, 0);


    for(int i=0; i<keylenth; i++) {
        for(int j=i; j<senlenth; j+=keylenth) {

           if((int)keymas[i]>=65 && (int)keymas[i]<=90) koef=64;
           if((int)keymas[i]>=97 && (int)keymas[i]<=122) koef=96;

            (int)massentence[j];
            (int)keymas[i];

            if(massentence[j]>=97 && massentence[j]<=122) {
            massentence[j]+=keymas[i]-koef;
            if(massentence[j]>122) massentence[j]-=26; }

            if(massentence[j]>=65 && massentence[j]<=90) {
            massentence[j]+=keymas[i]-koef;
            if(massentence[j]>90) massentence[j]-=26; }

            }

        }

           for(int i=0; i<senlenth; i++) cout<<massentence[i];

    getch();
}

Did you try the function tolower()? You could apply this to each character and perform any calculations to the result.

I took your code and translated it into C#. The only problem I had was with your white spacing...

Once I deleted your string literals and re-wrote them, the program produced the same output as your capitalised version except in lowercase.

Here is the code I used in C#:

class Test
    {
        static string _key, _sentence;
        static int _keyLength, _senLength;

        static void Main(string[] argv)
        {
            Console.WriteLine("Do not use spaces!");
            Console.Write("Key:  ");                    //enter the key

            _key = Console.ReadLine();

            _keyLength = _key.Length;

            byte[] keymas = new byte[_keyLength];
            keymas = Encoding.ASCII.GetBytes(_key);

            Console.Write("Enter the message: ");
            _sentence = Console.ReadLine();
            Console.Write("Ciphered message: ");

            _senLength = _sentence.Length;


            byte[] massentence = new byte[_senLength];
            massentence = Encoding.ASCII.GetBytes(_sentence);

            byte koef = 0;

            for (int i = 0; i < _keyLength; i++)
            {
                for (int j = i; j < _senLength; j += _keyLength)
                {

                    if (keymas[i] >= 65 && keymas[i] <= 90) koef = 64;
                    if (keymas[i] >= 97 && keymas[i] <= 122) koef = 96;

                    if (massentence[j] >= 97 && massentence[j] <= 122)
                    {
                        massentence[j] += (byte)(keymas[i] - koef);
                        if (massentence[j] > 122) massentence[j] -= 26;
                    }

                    if (massentence[j] >= 65 && massentence[j] <= 90)
                    {
                        massentence[j] += (byte)(keymas[i] - koef);
                        if (massentence[j] > 90) massentence[j] -= 26;
                    }

                }

            }

            for (int i = 0; i < _senLength; i++) Console.Write(Encoding.ASCII.GetString(massentence, i, 1));

            Console.ReadLine();
        }
    }

PS. I know the code isn't billiant for C#. I tried to keep it as close to the original as possible but this means there is some redundancy.

gerard4143, no, I need both upper and lower case letters
Ketsuekiame, thank you, but I need this in C++. Still can't understand what's wrong with the code

The maximum value of char is 127. On the third pass of j in the third pass of i, the value of massentence[j] should be 140, but the max value is 127, so it wraps around and becomes negative.

In the if statement if (massentence[j]>122) massentence[j] -= 26; if you check that the value is below 0 and subtract 26 from that too you should get readable output.

the other option is to use unsigned char, which increases the limit to 255.

Ketsuekiame, but now I have no idea how to fix the code... which lines should be changed?

A few things with your code:

As was pointed out using unsigned char gives you more predictable results

Using the islower/isupper methods to set the appropriate offset to the character code block simplifies your code tremendously

The modulus operator(%) creates further simplification by allowing your values to wrap around and stay within the range you want.

Here's some code to look at:

string Encrypt(string input, string key,bool encrypt)
{
    int ecrypt = (encrypt ? 1 : -1);
    string output;
    for(int i = 0; i< key.length();i++)
    {
        key[i] = tolower(key[i]);
    }
    for(int i = 0; i < input.length(); i++)
    {
        unsigned char temp = input[i];
        int offset = (isupper(temp) ? 65 : islower(temp) ? 97 : 0);
        if(offset > 0)
        {
            //This converts the character codes their appropriate index in the alphabet.
            //The key index is calculated by using the modulus of i and the length of the key string
            //Then performs either an addition or subtraction dpeneding on the value of the encrypt boolean
            //The result is then applied to the moduilus operator to get a new alphabet index
            //This is then added to the character code offset for the appropriate set of character codes.
            temp= (unsigned char)(((temp - offset) + ((key[i % (key.length())] - 97) * ecrypt) % 26) + offset);
        }
        else
            return "Invalid string";
        output +=temp;
    }
    return output;
}

This function takes 3 arguments the string to encrypt or decrypt, the string to use as the key, and a boolean to set whether you want encryption(true) or decryption(false), and returns the processed string. If there is an invalid character in the string the function will return a string that says "Invalid string".

For simplicity I forced the key to lower case.

commented: +1 for expanding the explanation +11
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.