С Цезарь Cipher Функция вызова не ведет себя, как ожидалось
Я пытаюсь построить программу, которая будет делать простой Цезарь шифр в текстовом файле с одиночными строками без пробелов в каждой строке. По какой-то причине моя функция шифрования не смещает текст, и я обрезаю строки различной длины символов. Можете ли вы увидеть, где я запутался с вызовом функции в цикле while?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define FILE_NAME "./infile.txt"
void caeser (char * ch, int shift)
{
int i = 0;
int len = strlen(ch);
while (ch[i] < len)
{
if (islower(ch[i]))
ch[i] = ((ch[i] - 'a' + shift) % 26 + 'a');
else
ch[i] = ((ch[i] - 'A' + shift) % 26 + 'A');
}i++;
printf("Caesar Cipher = %s\n", ch);
}
int main(void)
{
char * c = malloc( sizeof(char) * 1000);
FILE* fp = fopen (FILE_NAME, "r");
if (fp == NULL)
{
printf("Can't open %s\n", FILE_NAME);
exit(EXIT_FAILURE);
}
while(fgets(c, sizeof(c), fp) != 0)
{
printf("%s\n", c);
caeser(c, 1);
}
fclose(fp);
fp = NULL;
return 0;
}
2 ответа
Я сделал несколько изменений в вашем коде и выделил их жирным шрифтом.
Массив начинается с 0 и заканчивается символом n-1.
Вы проверили, если ch [i] в каждой итерации вам нужно увеличивать i на 1., чтобы вы могли получить следующий символ. для лучшего дизайна попробуйте добавить формат для печати в основную функцию вместо печати в функции. Вы должны вернуть указатель на строку и вывести его в main.#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define FILE_NAME "./infile.txt"
void caeser (char * ch, int shift)
{
int i = 0;
int len = strlen(ch);
while (**i < len-1**)
{
if (islower(ch[i]))
{
ch[i] = ((ch[i] - 'a' + shift) % 26 + 'a');
**i++;**
}
else
{
ch[i] = ((ch[i] - 'A' + shift) % 26 + 'A');
**i++;**
}
}
printf("Caesar Cipher = %s\n", ch);
}
int main(void)
{
char * c = malloc( sizeof(char) * 1000);
FILE* fp = fopen (FILE_NAME, "r");
if (fp == NULL)
{
printf("Can't open %s\n", FILE_NAME);
exit(EXIT_FAILURE);
}
while(fgets(c, sizeof(c), fp) != 0)
{
printf("%s\n", c);
caeser(c, 1);
}
fclose(fp);
fp = NULL;
return 0;
}
Обратите внимание, что fgets
может вернуть "символ новой строки" ('\n'
) в конце строки. Вы можете удалить символ новой строки из буфера.
Если в строке есть пробелы, '\n'
символ или любые символы, не входящие в диапазон AZ или az, затем игнорируйте эти символы, поскольку они не соответствуют логике для шифра caeser.
char * c = malloc( sizeof(char) * 1000); while(fgets(c, sizeof(c), fp) != 0) { ... }
Как уже упоминалось в комментариях, c
это указатель и sizeof(c)
обычно 4 или 8 в этом случае. Итак, вы говорите fgets
читать максимум 4 или 8 байтов. Но каждая строка в файле может быть намного длиннее. Если вы заявили, скажем char c[1000];
затем sizeof(c)
было бы 1000
, В противном случае не используйте sizeof
оператор здесь.
while(i < len) {...}i++;
Вы хотите добраться до конца строки и увеличивать ее внутри цикла, поэтому измените условие на:
while(i < len) {... i++;}
И, наконец, c
или же ch
обычно используется для обозначения символа. Это неформально и не имеет большого значения, но более понятно buf
или же str
если вы объявляете строку.
Пример:
void caeser(char *buf, int shift)
{
int i = 0;
int len = strlen(buf);
while(i < len)
{
char c = buf[i];
if(c >= 'a' && c <= 'z')
buf[i] = (c - 'a' + shift) % 26 + 'a';
else if(c >= 'A' && c <= 'Z')
buf[i] = (c - 'A' + shift) % 26 + 'A';
//else, do nothing if chararacter is not between a-z or A-Z
i++;
}
}
int main(void)
{
FILE* fp = fopen(FILE_NAME, "r");
if(fp == NULL)
{
printf("Can't open %s\n", FILE_NAME);
exit(EXIT_FAILURE);
}
int buf_size = 1000;
char *buf = malloc(sizeof(char) * buf_size);
while(fgets(buf, buf_size, fp))
{
//optional: remove the new line character if any
int len = strlen(buf);
if(len && buf[len - 1] == '\n')
buf[len - 1] = 0;
printf("plain : %s\n", buf);
caeser(buf, 1);
printf("cipher: %s\n\n", buf);
}
//free the buffer allocated with malloc
free(buf);
fclose(fp);
return 0;
}