Проблема с повторяющимися символами в строке - PullRequest
0 голосов
/ 26 мая 2020

Я просто пишу код в C, который шифрует строку с помощью ключа, введенного пользователем. Ключ, введенный пользователем, имеет 4 требования:

  • Это должно быть одно слово
  • Он должен состоять из 26 символов
  • Он может содержать только буквы c символов
  • Он не может содержать повторяющиеся символы

Проблема связана с четвертым требованием, так как проверка дублирования не всегда работает должным образом (я пробовал с ключом YFDTSMPBVIERGHEWONUAKLQXCZ, который содержит 2 раз буква «Е», и этот ключ принимается программой). Я хотел бы знать, в чем может быть проблема, если вы можете помочь; внизу вы можете найти код программы:

#include <cs50.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

int main(int argc, string argv[])

{

    //Check if there is a number of command-line arguments different than 1
    //And return an error message
    if (argc != 2)
    {
        printf("Usage: ./substitution KEY\n");
        return 1;
    }

    //Check if the lenght of the string is  more or less than 26 characters
    //And return an error message
    else if (strlen(argv[1]) != 26)
    {
        printf("Key must contain 26 characters\n");
        return 1;
    }

    else
    {

        //Check if the command-line argument is alphabetic, and compare the
        //Number of characters in the argument with the argument lenght; if
        //The two  values correspond,  then the string  is considered valid
        //Otherwise the system will return an error message
        int index = 0, j;
        string s = argv[1];

        for (j = 0; s[j] != '\0'; j++)
        {
            if ((s[j] >= 'A' && s[j] <= 'Z') || (s[j] >= 'a' && s[j] <= 'z'))

            {
                index++;
            }
        }

        if (strlen(argv[1]) != index)
        {
            printf("Key must only contain alphabetic characters\n");
            return 1;
        }

        else
        {

            //Check if the command-line  argument contains characters that
            //Are repeated;  in this case the system  will return an error
            //Message
            int count;
            for (int z = 0; z < strlen(s); z++)
            {
                count = 1;

                for (j = z + 1; j < strlen(s); j++)
                {

                    if (s[z] == s[j] && s[z] != ' ')
                    {
                        count++;
                    }

                }
                if (count > 1 && s[z] != '0')
                {
                    printf("Key must not contain repeated characters\n");
                    return 1;
                }

                else
                {

                    //Ask the user for a string to be encrypted
                    string plaintext = get_string("plaintext : ");

                    {
                        printf("ciphertext: ");
                    }


                    { 
                        //Starts loop check into plaintext
                        for (int i = 0; i < strlen(plaintext); i++)

                        {
                            //Start loop check into key
                            for (int jax = 0; jax < 26; jax++)

                            {
                                //Check coherence between lower cases in the same character of both plaintext and key
                                if (islower(
                                        plaintext[i]))

                                {
                                    if (plaintext[i] == 'a' + jax)

                                    {
                                        printf("%c", tolower(s[jax]));
                                    }

                                }
                                //Check coherence between lower cases in the same character of both plaintext and key
                                else if (isupper(
                                             plaintext[i]))
                                {
                                    if (plaintext[i] == 'A' + jax)
                                    {
                                        printf("%c", toupper(s[jax]));
                                    }
                                }
                            }

                            //If it is not an alphabetical character, just print  it as
                            //is on screen
                            if (!isalpha(plaintext[i]))
                            {
                                printf("%c", plaintext[i]);
                            }
                        }
                        printf("\n");
                        return 0;
                    }
                }
            }
        }
    }
}

1 Ответ

0 голосов
/ 26 мая 2020

Предложите упростить проверку на дубликаты и выделить в рутину. Вероятно, есть способ получше, вот быстро сгенерированная версия:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define AMAX 128
char *key = "YFDTSMPBVIERGHEWONUAKLQXCZ";

static int
check_key(char *str)
{
    char counts[AMAX];
    int rv = 0;

    memset(counts, 0, sizeof (counts));
    for (; *str; str++) {
        if (*str > (AMAX - 1)) {
            printf("bad char in key\n");
            exit(1);
        }
        if (++counts[*str] > 1) {
            printf("found duplicate '%c'\n", *str);
            rv = 1;
            break;
        }
    }

    return (rv);
}


int
main(void)
{
    int rv;

    rv = check_key(key);
    if (rv)
        printf("key cannot contain duplicates\n");
    else
        printf("key is OK\n");

    return (rv);
}
...