Как обернуть в алфавитном порядке z на a и от Z на A после сдвига каждой буквы на определенное количество мест? - PullRequest
2 голосов
/ 13 июля 2020

Я работаю над кодом, в котором я сдвигаю каждую букву на одно место, поэтому (a) становится (b), а (b) становится (c) и так далее. Пока мне это удалось, но я столкнулся с проблемой переноса заглавной буквы (Z) в (A). Кажется, я не могу понять лог c, как это сделать. Любая помощь будет оценена. Большое спасибо.

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

int main(void)
{
    //prompt the user to type in a text.
    string p = get_string("plaintext: ");
    
    //create a variable to refer to the length of the string.
    int n = strlen(p);
    
    
    for (int i = 0; i < n; i++)
    {
        //check if all chars (i) in the string (p) are alphabetical then increment i by 1.
        if (isalpha(p[i]))
        p[i]++;

        {
            //check if i has gone beyond the letter (z) and (Z).
            if ((p[i] > 'z') && (p[i] > 'Z'))
            {
                //if so then subtract 26 letter after z or Z to get back to a or A.
                p[i] = p[i] - 26;
            }

        }
        printf("%c", p[i]);
    }
    printf("\n");
}

Ответы [ 2 ]

2 голосов
/ 13 июля 2020

другой способ ближе к исходной программе - просто заменить

if ((p[i] > 'z') && (p[i] > 'Z'))

на

if ((p[i] == 'z'+1) || (p[i] == 'Z'+1))

, чтобы избежать дублирования почти всего кода, как это это случай в другом ответе

И я думаю, что удобнее заменить

p[i] = p[i] - 26;

на

p[i] -= 'z' - 'a' + 1;

Компилятор заменяет 'z' - 'a' + 1 на его значение и выражение объясняет цель сама по себе

И до финиша sh Я думаю, что проще сделать

if (isalpha(p[i]))
{
  if ((p[i] == 'z') || (p[i] == 'Z'))
    p[i] -= 'z' - 'a';
  else
    p[i] += 1;
}

и удалить приращение бесплатно

или иметь только одну строку:

if (isalpha(p[i]))
  p[i] += ((p[i] == 'z') || (p[i] == 'Z')) ? 'a' - 'z' : 1;

но это, вероятно, менее читабельно

Из них

printf("%c", p[i]);

стоит дорого и может быть заменен на

putchar(p[i]);
1 голос
/ 13 июля 2020

Вам необходимо разделить ваши приращения / проверки на блоки верхнего и нижнего регистра, потому что, хотя символы a ... z и A ... Z , скорее всего, будут последовательными, они будут разными последовательностей.

Что-то вроде этих строк для вашего l oop:

    for (int i = 0; i < n; i++) {
        //check if all chars (i) in the string (p) are alphabetical then increment i by 1.
        if (islower(p[i])) { // Lowercase letter check ...
            p[i]++;
            //check if i has gone beyond the letter (z).
            if (p[i] > 'z') {
                //if so then subtract 26 letter after z to get back to a.
                p[i] = p[i] - 26;
            }

        }
        else if (isupper(p[i])) { // Uppercase letter check ...
            p[i]++;
            //check if i has gone beyond the letter (Z).
            if (p[i] > 'Z') {
                //if so then subtract 26 letter after Z to get back to A.
                p[i] = p[i] - 26;
            }

        }
        printf("%c", p[i]);
    }

(Кроме того, я предполагаю, что в вашем коде есть { после p[i]++; - это опечатка. В противном случае вы проверяете каждый символ, даже если это не буква. Ваш отступ предполагает, что это не то, что вы намеревались.)

...