【问题标题】:why the cipher message contain letters which isn't belong to ASCII code为什么密码消息包含不属于 ASCII 码的字母
【发布时间】:2022-09-22 23:22:07
【问题描述】:

我实际上正在尝试制作一个加密消息的代码,以便我可以在 cmd 中输入任何文本消息作为输入,并对字母字母进行加密并保留其他字母,但是当我尝试这样做时,我得到了意外的输出带有额外字母的消息有人可以向我解释发生了什么吗?

当我使用命令./substitution VCHPRZGJNTLSKFBDQWAXEUYMOIa 作为输入运行程序时,它应该输出v,但它不会只输出v

或“你好,艾哈迈德。你在哪里?希望你一切都好。”作为输入,“Jrssb, Vjkrp. Yjrwr vwr obe ? Jbdr obe vwr pbnfg yrss.\”作为输出。

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

int main(int argc, string argv[])
{
    string alphabet = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";
    bool check_alpha = true;
    bool loop_check_alpha = true;
    //int i;
    //string key = argv
    //printf(\"key is %s with length %i and alphabet letters are %lu letter\\n\", argv[1], argc, strlen(alphabet));
    if (argc < 2 || argc > 2)
    {
        printf(\"Usage: ./substitution key\\n\");
    }
    else if (argc == 2)
    {
        for (int i = 0 ; i < strlen(argv[1]) ; i++)
        {
            if (isalpha(argv[1][i] != 0))
            {
                check_alpha = false;
            }
        }
        if (strlen(argv[1]) == 26)
        {
            string message = get_string(\"plaintext:  \");
            int cipher_width = 200;
            //get_int(\"put the width of your message: \");
            char cipher[cipher_width];
            int cipher_num = 0;
            //printf(\"plaintext:  %s\\n\", message);
            while (loop_check_alpha)
            {
                if (check_alpha == true)
                {
                    //loop_check_alpha = false;
                    //printf(\"check_alpha is %s\\n\", check_alpha ? \"true\" : \"false\");
                    for (int i = 0 ; i < strlen(alphabet) ; i++)
                    {
                        //printf(\"key letter %i is %c\\n\", i, argv[1][i]);
                        //cipher_num = 0;
                        for (int j = 0 ; j < strlen(message) ; j++)
                        {
                            if (message[j] == tolower(alphabet[i]) || message[j] == toupper(alphabet[i]))
                            {
                                if (message[j] == tolower(alphabet[i]))
                                {
                                    cipher[j] = tolower(argv[1][i]);
                                    //if (strlen(message) < strlen(cipher))
                                }
                                else if (message[j] == toupper(alphabet[i]))
                                {
                                    cipher[j] = toupper(argv[1][i]);
                                }
                                //cipher_num += 1;
                                //printf(\"New added letter is %c\\n\", argv[1][i]);
                            }
                            else if (isalpha(message[j]) == 0)
                            {
                                cipher[j] = message[j];
                                //printf(\"%c from message is printed\\n\", message[j]);
                            }
                            //printf(\"cipher[j] is %c, message[j] is %c, alphabet[i] is %c and argv[1][i] is %c\\n\", cipher[j], message[j],
                            //alphabet[i], argv[1][i]);
                        }
                    }
                    printf(\"message length is %lu and cipher length is %lu\\n\", strlen(message), strlen(cipher));
                    printf(\"ciphertext: %s\\n\", cipher);
                    //if (strlen(message) == strlen(cipher))
                    loop_check_alpha = false;
                }
            }
        }
    }
}
  • 您是否尝试在调试器中逐行运行代码,同时监视所有变量的值,以确定您的程序在哪一行停止按预期运行?如果您没有尝试过,那么您可能想阅读以下内容:What is a debugger and how can it help me diagnose problems? 您可能还想阅读以下内容:How to debug small programs?
  • 请注意,CS50 有自己的调试器,称为debug50
  • 是的,我这样做了,发现当它使用 J 增量因子检查第二个 for 循环中的 if 语句并且 2 个 if 得出错误结果时,它会将非 ascii 字母添加到密码值,但代码中没有任何内容这样做。所以为什么 ?
  • 旁注:您可以将if (argc &lt; 2 || argc &gt; 2) 更改为if ( argc != 2 ),也可以将else if (argc == 2) 行更改为else。这不会改变程序的行为,但更简单,更易于阅读。
  • 您可以将其视为命令 ./substitution VCHPRZGJNTLSKFBDQWAXEUYMOI 和 a 作为输入,假设输出 v 但它不只输出 v

标签: c for-loop encryption while-loop cs50


【解决方案1】:

printf%s 转换格式说明符一起使用时,您需要将一个以null 结尾的字符串作为参数传递给函数。

然而,在行

printf("ciphertext: %s\n", cipher);

cipher 不一定由空终止字符终止,因为您从未将任何字符设置为该值。

这解释了为什么您的程序在预期字符之后打印“垃圾”字符。函数printf 可能会将它在内存中找到的所有内容都打印为一个字符,直到它碰巧找到一个空字符。

因此,要解决此问题,您可以在cipher 中添加终止空字符,也可以限制printf 打印的字符数,例如:

printf( "ciphertext: %.*s\n", (int)strlen(message), cipher );

如果你想通过添加终止空字符来解决问题,我建议你在内循环之后立即写cipher[j] = '\0';。但是,由于j 在循环结束后立即退出scope,因此您必须将j 的声明移到内部循环之外,方法是在循环外部添加int j; 并更改行

for (int j = 0 ; j < strlen(message) ; j++)

至:

for (j = 0 ; j < strlen(message) ; j++)

【讨论】:

    猜你喜欢
    • 2021-02-22
    • 1970-01-01
    • 2016-11-30
    • 1970-01-01
    • 2012-05-18
    • 1970-01-01
    • 2017-07-05
    • 2019-12-15
    • 2021-06-30
    相关资源
    最近更新 更多