Как я могу изменить каждый символ в строке, но не изменить пунктуацию в C? - PullRequest
1 голос
/ 20 сентября 2019

У меня есть задание для создания программы, которая преобразует каждый символ в строке по заданному номеру, введенному в командной строке.Пример: если пользователь вводит 1 в командной строке, затем вводит abc, def, тогда программа должна преобразовать строку в bcd, efg.

Я написал программу, но не могу понять, как ее получитьпрограмма не преобразует знаки препинания.

Программа в настоящее время преобразует abc, def и печатает bcdefg.Необходимо напечатать bcd, efg и включить знаки препинания без их преобразования.

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

int main(int argc, string argv[]) //user enter number at cmd prompt

{
    string key = argv[1]; //store user entered number
    int k = atoi(argv[1]); //only accept consecutive digits
    if (argc != 2 || k == 0) 
    {    
        printf("Usage: ./caesar key\n"); /*show error if user enters non-consecutive digits*/
        return 1;
    }
    string original = get_string("Plaintext: "); /* prompt user for message to spin*/

    for (int i = 0, n = strlen(original); i < n; i++)  /* get string length and loop char change*/            
        if (isalnum(original[i])) /* only convert alphanumeric character*/                    
            printf("%c", original[i] + k); /* print and convert character by number entered at prompt*/

    printf("\n");
    return 0;
}

Ответы [ 2 ]

1 голос
/ 21 сентября 2019

Вы выводите только те символы, которые вы преобразовываете (те, которые находятся в наборе isalnum).Вам также необходимо вывести символы без преобразования.Например:

    char cipher = original[i] ;
    if( isalnum( original[i] )
    {
        cipher += k ;
    }

    printf( "%c", cipher ) ;

Однако описанный алгоритм по-прежнему глубоко ошибочен в нескольких аспектах, но неясно, является ли это присвоение ошибочным (в этом случае это не ваша проблема) или вашописание назначения является неточным.

Более практичное решение может выглядеть следующим образом:

#include <ctype.h>

char caesar( char x, int key )
{
    const char alphabet[] = {'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',
                             '0','1','2','3','4','5','6','7','8','9'};

    char cipher = x  ;

    for( int i = 0;
         cipher == x && i < sizeof( alphabet );
         i++ )
    {
        if( alphabet[i] == tolower( x ) )
        {
            cipher = alphabet[(i + key) % sizeof( alphabet )] ;
            if( isupper( x ) )
            {
                cipher = toupper( cipher ) ;
            }
        }
    }

    return cipher ;
}

Тогда ваш цикл вывода будет выглядеть следующим образом:

for( int i = 0; original[i] != '\0' ); i++)
{
    printf("%c", ceasar( original[i], k ) ) ;
}
0 голосов
/ 20 сентября 2019

То, что вы сейчас делаете, печатает символ + k, только если он буквенно-цифровой, но не печатает его иначе.Вы действительно хотите добавить только 1002 *, если оно буквенно-цифровое.С небольшой логической логикой и математикой мы можем полностью избежать оператора if.

printf("%c", original[i] + (k * !!isalnum(original[i])));

Если isalnum вернет true, !! сделает результирующее значение 1 (оно может вернуть ненулевое значениеесли истина, двойное отрицание логически сделает либо 1, если истина, либо 0, если ложь).Итак, теперь мы добавляем k, если он буквенно-цифровой, или ничего не добавляем иначе, и печатаем символ в любом случае.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...