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 中)?的主要内容,如果未能解决你的问题,请参考以下文章
Java 中的 Vigenere/Polyalphabetic Cipher Decoder/Decrypter/Breaker