Vigenere cs50 Pset2 末尾的额外字符

Posted

技术标签:

【中文标题】Vigenere cs50 Pset2 末尾的额外字符【英文标题】:Extra Characters at the end of Vigenere cs50 Pset2 【发布时间】:2019-05-13 23:39:39 【问题描述】:

我是编码新手,已经做了几个星期了。我现在正在学习 cs50 课程,并且我已经为 pset2 vigenere 编写了代码。当我使用 check50 时,我意识到它希望我在不跳过键的情况下考虑空格和非字母。

我添加了“j--;”而且,虽然代码是正确的,但它现在在密文末尾创建了额外的随机字符。

此外,当我在我的代码中检查 argv[1] 中的字母时,我有一个 if 语句,其中包含“int key = argv[1][i];”在身体里。它什么也没做,但我不知道如何让它继续检查下一个字符而没有空的正文,这是不允许的。

任何帮助将不胜感激!非常感谢你!

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


int main(int argc, string argv[0])


    //making sure it is not more than one command line
    if (argc != 2)
    
        printf("Usage: ./vigenere key \n");
        return 1;
    

    //if it is one command line, making sure the input is just letters      
    if (argc == 2)
    
        for (int i = 0, n = strlen(argv[1]); i < n; i++)
        
            if (isalpha(argv[1][i]))
                
                int key = argv[1][i];
            
            else
            
                printf("Usage: ./vigenere key \n");
                return 1;
            
           

    
    //asking user for input text
    string plaintext = get_string("plaintext: ");
    printf("ciphertext:");

    //going through a loop to turn plain text into ciphertext 
    int i = 0; 
    int n = strlen(plaintext); 
    string key = argv[1];


    //looping through the key    
    while (i < n)

    

        for (int j = 0, m= strlen(key); j < m; j++, i++)

           
            //using the asci of each char as an int
            int asc = (plaintext[i]);
            int k = key[j];
            //if lowercase
            if (k >= 97 && k <= 122)
            
                k -= 97;
            
            else
            
                k -= 65;
            

            //if lowercase
            if (asc >= 97 && asc <= 122)
            
                printf("%c", ((((asc - 97) + k) % 26) + 97));
            
            //if uppercase
            else
            
                if (asc >= 65 && asc <= 90)
                
                    printf("%c", ((((asc - 65) + k) % 26) + 65));
                
                //if non-letter
                else
                  
                    printf("%c", asc);
                    j--;

                
            

          


    


    printf("\n");

      

这些是预期结果与实际结果:

key: baz
plaintext: hello, world!
expected ciphertext: iekmo, vprke!

actual ciphertext:   iekmo, vprke!!pu

【问题讨论】:

您是否查看了带有标签cs50 和vigenere 的其他问题,以了解这些程序(可能答案中的程序比问题中的程序更多)是如何做到的?如果你在搜索区域输入[c] [cs50] [vigenere],你会得到 71 个问题,包括这个问题。其中某处是您需要的洞察力。 “额外字符”最常见的原因是您没有正确地终止您的字符串 - 您是否检查过您是否对字符串进行了空终止。 你有int main(int argc, string argv[0])——0 是非正统的,最好省略。最好在stderr 上报告错误(使用fprintf(stderr, …) 代替printf(…))。当没有键时,以及键中有非字母字符时,您会报告使用错误。当提供了密钥但包含非字母字符时,最好使用不同的错误消息。 感谢您的提示! OT: about: printf("Usage: ./vigenere key \n"); 1) 错误信息应该输出到stderr 而不是stdout。 2)同一个可执行文件不关心可执行文件的名称,所以应该使用实际名称,如:argv[0] 一个有用的例子是:fprintf( stderr, "Usage: %s &lt;key&gt;\n", argv[0] ); 【参考方案1】:

因为程序在此处增加i for (int j = 0, m= strlen(key); j &lt; m; j++, i++),它允许读取明文末尾。在 for 循环完成之前,while 循环不会计算 i。这有可能导致无限循环,具体取决于明文结束后内存的内容。如果它永远不会遇到 a-z 或 A-Z 范围内的东西,它将永远j--

i == strlen(plaintext) 时,你需要跳出for循环。

【讨论】:

哇,这太明显了!有用!!非常感谢!!

以上是关于Vigenere cs50 Pset2 末尾的额外字符的主要内容,如果未能解决你的问题,请参考以下文章

我的代码有啥问题? (Vigenere cypher cs50, pset2)

如何在 vigenere cipherkey cs50 pset2 中重用(循环)密钥

为啥 Vigenere 失败 (CS50x)?

CS50 - pset2 - 维吉尼

CS50 PSet 2:Vigenere 密码分段错误

CS50 Pset2。维吉内尔。大文本到低键,反之亦然问题