2015-08-03 3 views
0

Я новичок в программировании, и я пытаюсь написать программу на C для Caesar Cipher.Нужна помощь в Caesar Cipher in C

Ввод состоит из целой длины длины, равной длине строки, за которой следует строка str и целочисленное шифрование.

Мой вход:

11 
middle-Outz 
2 

Выход:

[email protected] 

Обязательный выход:

okffng-Qwvb 

Ниже приведен код, который я написал. Может ли кто-нибудь помочь мне, почему я получаю последний символ в выводе!

Я совершенно не знаю.

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

int main() 
{ 
    int ilength = 0, encrypt = 0, i = 0, j = 0; 

    char alph_base[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'X', 'Y', 'Z', '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'}; 

    scanf("%d", &ilength); 
    char str[ilength + 1]; 
    scanf("%s", str); 
    scanf("%d", &encrypt); 
    //printf("%c\n", str[5]); 

    char outputString[ilength + 1]; 
    char temp[ilength + 1]; 

    for (j = 0; j <= ilength; j++) 
    { 
    temp[j] = str[j]; 
    i = 0; 

    if (str[j] == '\0') 
    { 
     outputString[j] = '\0'; 
    } 

    while ((i >= 0) && (i < 26)) 
    { 
     if (temp[j] == alph_base[i]) 
     { 
     if (i == 25 && encrypt == 0) 
     { 
      outputString[j] = alph_base[25]; 
     } 

     if ((i + encrypt) == 26) 
     { 
      outputString[j] = alph_base[(i + encrypt) % 26]; 
     } 
     else 
      outputString[j] = alph_base[(i + encrypt) % 26]; 
     } 
     if ((temp[j] < 65 || temp[j] > 90) && temp[j] < 97) 
     outputString[j] = temp[j]; 

     if ((temp[j] < 97 || temp[j] > 122) && temp[j] > 90) 
     outputString[j] = temp[j]; 

     i++; 
    } 

    while ((i > 25) && (i < 52)) 
    { 
     if (temp[j] == alph_base[i]) 
     { 
     if (i == 51 && encrypt == 0) 
     { 
      outputString[j] = alph_base[51]; 
     } 

     if ((i + encrypt) == 51) 
     { 
      outputString[j] = alph_base[51]; 
     } 

     if ((i + encrypt) > 51) 
     { 
      outputString[j] = alph_base[((i + encrypt) % 51) + 25]; 
     } 
     else 
      outputString[j] = alph_base[(i + encrypt) % 51]; 
     } 
     if ((temp[j] < 65 || temp[j] > 90) && temp[j] < 97) 
     outputString[j] = temp[j]; 

     if ((temp[j] < 97 || temp[j] > 122) && temp[j] > 90) 
     outputString[j] = temp[j]; 
     i++; 
    } 
    } 
    printf("%s\n", outputString); 
    return 0; 
} 
+1

После условного блока 'if (str [j] == '\ 0') {...}' вам, вероятно, придется обернуть остальную часть тела цикла 'else {...} '. –

+0

@Giorgi: Я очень новичок в кодировании. Сделаю все возможное, чтобы улучшить. Спасибо –

+0

@squeamishossifrage: Хорошо проверит с этим. Спасибо –

ответ

2

Ваш код является слишком сложным для того, что вы хотите сделать.

Ваша проблема связана с возвратом от 'z' до 'a'.

Простая функция, как это может сделать работу для персонажа:

#include <ctype.h> 

char caesar_encrypt(char input, int key) 
{ 
    char output = input; 
    char base, offset; 
    // If not a letter, return the char unmodified 
    if (! isalpha(input)) 
    { 
     return output; 
    } 

    base = isupper(input) ? 'A' : 'a'; // Check if upper/lower case 
    offset = input - base; // Take offset from 'a' 
    offset += key; // Add key to offset 
    offset %= 26; // Wrap offset to the 26 letters 

    output = base + offset; 
    return output; 
} 

Многие идеи здесь:

  1. Используйте функции из <ctype.h> (isalpha, isupper), что позволяет избежать многих Comparaisons в ваш код.

  2. Рассмотрите ваши символы как «смещение» от буквы A (в верхнем или нижнем регистре A). Таким образом, вы работаете с числами в диапазоне [0;25], и вы можете обернуть с помощью простого модуля

  3. Чаротераторы являются «целыми числами», поэтому их можно добавить или вычесть. Чтобы получить третью букву прописного алфавита, вы можете сделать char c = 'A' + 2;, что проще, чем ваш огромный массив.

Отказ от ответственности: Код, написанный здесь, не тестируется, может содержать опечатки;)

+1

Спасибо тонну. Я не знал об этих полезных функциях в

+0

работал как шарм! Благодарю. Ключевым обучением является то, что я могу использовать функции и что символы могут быть добавлены/вычтены. –

0

идеальный ответ на NiBZ. Чтобы добавить к этому, если вы все еще хотите, чтобы писать свои собственные проверки, а не использовать библиотечные функции, которые вы можете сделать что-то вроде:

int my_isalpha(char c){ 
    return ((c >= 'a' && c <= 'z')|| (c >= 'A' && c <= 'Z')); 
} 

int my_isupper(char c){ 
    return (c >= 'A' && c <= 'Z'); 
} 

Внимание: Над реализацией отлично подходит для ASCII, но не так хорошо для ISO 8859-1 или его родственников. Ссылка: https://stackoverflow.com/a/2169293/5183246

+0

Спасибо @d_geeks. Я тоже попробую –