繁体   English   中英

C Caesar 密码函数调用未按预期运行

[英]C Caesar Cipher Function Call Not Behaving as Expected

我正在尝试构建一个程序,该程序将对文本文件执行简单的凯撒密码,每行没有空格的单个字符串。 出于某种原因,我的密码函数没有移动文本,我正在以不同长度的字符切断字符串。 你能看到我在 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;
}

我对您的代码进行了一些更改,并用粗体标记了它们。

数组从 0 开始,以 n-1 个字符结束。

你检查过 ch[i] < len。 ch[i] 是数组中 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++;}

最后, cch通常用于表示一个字符。 这是非正式的,并不重要,但如果您要声明字符串,使用bufstr更清楚。

例子:

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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM