Vigenere Cipher - 如何忽略纯文本中的空格(在 C 中)?

Posted

技术标签:

【中文标题】Vigenere Cipher - 如何忽略纯文本中的空格(在 C 中)?【英文标题】:Vigenere Cipher - How to ignore Spaces in the plain text (in C)? 【发布时间】:2019-02-16 21:01:47 【问题描述】:

加粗是我试图让程序在输出时忽略纯文本中的空格。我对如何做到这一点感到困惑。当我运行程序时,它不会忽略空格。相反,它的运行就像加粗的 else if 语句不存在一样。我很困惑为什么会这样。如果我的代码有点乱,我很抱歉。我刚开始编程。

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

int shift(char c);

int main(int argc, string argv[])

    // Check to see if two arguments are enterted at launch 
    int cipher = 0;
    if (argc != 2)
    
        // If not return error & return 0
        printf("Usage: ./vigenere keyword \n");
        return 1;
    
    else
    
        int strlength = strlen(argv[1]);
        // Iterates through characters in second argument (key), checking to see 
        // if they are digits
        for (int k = 0; k < strlength; k++)
        
            if (!isalpha(argv[1][k]))
            
                // If not return error & return 1
                printf("Usage: ./vigenere keyword\n");
                return 2;
            
        
        //char *c =argv[1];
        string plaintext = get_string("Plaintext: ");
        int len = (int)strlen(plaintext);
        //int b = atoi(c);
        char code[len];
        strcpy(code, plaintext);
        for (int j = 0; j < len; j++)
        
            int key = shift(argv[1][j]);

            if (isupper(argv[1][0]))
            
                cipher = ((((code[j] - 'A') + key) % 26) + 'A');
                //printf("%c", (((plaintext[j] - 'A') + key) % 26) + 'A');
                //printf("%c",cipher);  
            
            else if (islower(argv[1][0]))
            
                cipher = ((((code[j] - 'a') + key) % 26) + 'a');
                //printf("%c", (((plaintext[j] - 'a') + key) % 26) + 'a');
                printf("%c",cipher);  
            
            else if (!isalpha(code[j]))
            
                code[j] = 0;
            
            /* else
            
                printf("%c", code[j] + (cipher));
            
            */
        
        printf("\n");
    


int shift(char c)

    int i = c;
    if (i <= 'Z' && i >= 'A')
    
        return ((i - 'A') % 26);
    
    else
    
        return ((i - 'a') % 26);
    

【问题讨论】:

为什么不用if (!isalpha(argv[1][k])) 而不是if (isdigit(argv[1][k]))? (除非您允许标点符号)char code[len]; 必须是 char code[len+1];(对于 nul-terminating 字符)。你不需要else if (!isalpha(code[j])),只需要else,如果不是upper而不是lower,就不是alpha 谢谢!我做了那个改变。 另外,您担心打印的空间是多少?对于任何字符串,您可以使用 for (int i = 0; mystring[i]; i++) if (!isspace (mystring[i]) putchar (mystring[i]); putchar ('\n'); 打印每个非空格字符 我在输入纯文本时担心空格。 哦,有道理,那么你可以这样做,例如string newst = get_string ("input: "); char strnospc[strlen(newst)+1]; size_t ndx=0; for (int i = 0; newst[i]; i++) if (!isspace (newstr[i])) strnospc[ndx++] = newstr[i]; newstr[ndx] = 0; 现在strnospc 包含newstr 中内容的nul-terminated 副本,没有任何空格。 ndx 现在拥有长度 strnospc(与 strlen (strnospc) 相同)您可以在没有 get_string 的情况下执行相同的操作,只需使用 getchar() 读取具有相同测试的输入即可。 (由你决定) 【参考方案1】:

虽然您从未指出 cmets 是否足以解决您的问题,但如果您仍在纠结如何使用 CS50 get_string() 函数获取输入,同时确保它不包含 空格,那么您可以简单地为get_string() 函数编写一个简短的包装器。

在包装函数中,您可以简单地将任何提示直接传递给get_string(),保存返回。然后分配第二个字符串来保存内容并遍历 get_string() 返回的字符串,仅将非空白字符复制到新的内存块,完成后以 nul 终止新字符串并返回新字符串。

这可能很简单:

#include <cs50.h>
...
/* function using CS50 get_string() to fill input w/o spaces */
string get_str_nospc (string p)

    size_t ndx = 0;             /* index */
    string s = get_string (p),  /* string returned by get_string() */
        sp = s,                 /* pointer to s (must preserve s address) */
        s_nospc = NULL;         /* pointer to copy with no whitespace */

    if (!s)     /* validate get_string() return */
        return NULL;

    /* allocate/validate storage for string without whitespace */
    if (!(s_nospc = malloc (strlen (s) + 1))) 
        perror ("malloc-s_nospc");
        return NULL;
    

    do  /* copy s to s_nospc omitting whitespace */
        if (!isspace (*sp))         /* if it's not a space - copy */
            s_nospc[ndx++] = *sp;
    while (*sp++);  /* post-increment ensures nul-character copied */

    return s_nospc; /* return string with no whitespace */

(注意:无论get_string() 返回的字符串是否包含空格,您都需要分配和复制,因为get_string() 返回的字符串在退出时被CS50 库析构函数释放。您的函数不应该返回一个可能/可能不需要根据函数内的条件释放的字符串——你永远不会知道你是否负责调用free。)

一个简短的例子可以是:

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

#include <cs50.h>

/* function using CS50 get_string() to fill input w/o spaces */
string get_str_nospc (string p)

    size_t ndx = 0;             /* index */
    string s = get_string (p),  /* string returned by get_string() */
        sp = s,                 /* pointer to s (must preserve s address) */
        s_nospc = NULL;         /* pointer to copy with no whitespace */

    if (!s)     /* validate get_string() return */
        return NULL;

    /* allocate/validate storage for srting without whitespace */
    if (!(s_nospc = malloc (strlen (s) + 1))) 
        perror ("malloc-s_nospc");
        return NULL;
    

    do  /* copy s to s_nospc omitting whitespace */
        if (!isspace (*sp))         /* if it's not a space - copy */
            s_nospc[ndx++] = *sp;
    while (*sp++);  /* post-increment ensures nul-character copied */

    return s_nospc; /* return string with no whitespace */


int main (void) 

    string nospc = get_str_nospc ("input : ");

    if (nospc) 
        printf ("nospc : %s\n", nospc);
        free (nospc);
    

使用/输出示例

$ ./bin/cs50_getstrnospc
input : my dog has fleas
nospc : mydoghasfleas

检查一下,让我知道这是否是您上次评论的意图。如果没有,我很乐意提供进一步的帮助。

【讨论】:

以上是关于Vigenere Cipher - 如何忽略纯文本中的空格(在 C 中)?的主要内容,如果未能解决你的问题,请参考以下文章

C中的Vigenere Cipher:空间未被忽略

Vigenere Cipher使用命令行提示

我将如何在 python 中实现 vigenere 密码

将 Vigenere Cipher 排列成列

Java 中的 Vigenere/Polyalphabetic Cipher Decoder/Decrypter/Breaker

Vigenere-cipher 错误输出