【发布时间】:2021-07-14 22:34:28
【问题描述】:
以下是 CS50 课程练习的一部分。此处描述了完整的问题: https://cs50.harvard.edu/x/2021/psets/2/substitution/
简而言之:在命令行中,您提供一个 26 长的字母数组作为参数,这些字母将用于“加密”在运行时提示输入的字符串,称为纯文本。
然后循环遍历明文数组,并使用它们的 ascii 整数值(稍微简化)来索引作为命令行参数提供的“26 字母密钥”,从而“加密”初始明文字符串 (ptxt)并将其存储在一个新的密文字符串(ctxt)中。
问题我遇到的输入是纯文本 短 比 6 - 我用来将 ptxt 的长度存储在 'n 中的 strlen() 函数' 似乎返回 6。因此,如果我在纯文本提示符下仅键入字母 'a' - n 似乎设置为 6。
以下示例:
$ ./substitution YTNSHKVEFXRBAUQZCLWDMIPGJO
明文:a
密文:y.G[
密文长度为6
预期的输出只是 'y' ,但显然有些东西超出了界限 - 长度不应该是 6,而应该是 1。 让我抓狂的是 - 如果您在初始化 'n' 后取消注释 printf 语句,那么代码会突然起作用,您会得到以下信息:
$ ./substitution YTNSHKVEFXRBAUQZCLWDMIPGJO
明文:a
明文长度为 1
密文:是的
密文长度为 1
我在这里缺少什么? printf 调用如何以某种方式解决此问题?
让我发疯:)
#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
bool is_letter(string array);
char encrypt(string key, char c);
//Command Line input a key to 'encrypt' some plaintext inputted at runtime
int main(int argc, string argv[])
{
// if there are NOT 2 arguments OR the first argument is NOT just letters OR is not 26 letters
if (argc != 2 || !is_letter(argv[1]) || strlen(argv[1]) != 26)
{
printf("Usage: ./caesar key (where key must be 26 letters)\n");
return 1;
}
// prompt user for a plaintext string, store the length in n and initialize a ciphertext string with same length
string ptxt = get_string("plaintext: ");
int n = strlen(ptxt);
//printf("plaintext is %i long\n", n); //this is here to correct n (try commenting out this line and see what happens for ptxt < 6)
char ctxt[n];
for (int i = 0; i < n; i++)
{
ctxt[i] = encrypt(argv[1], ptxt[i]);
}
printf("ciphertext: %s\n", ctxt);
printf("ciphertext is %i long\n", (int) strlen(ctxt));
return 0;
}
// function that checks whether command line argument is all letters
bool is_letter(string array)
{
int n = strlen(array);
for (int i = 0; i < n; i++)
{
if (!isalpha(array[i])) //loop over string - if any char is not a letter - return false
{
return false;
}
}
return true; //reaching this means all chars in the string are a letter - return true
}
//function that takes a key and a char and returns the "encrypted" char
char encrypt(string key, char c)
{
if (isalpha(c))
{
int n = 0;
char letter = 0;
if (isupper(c))
{
n = c - 65;
letter = key[n];
return toupper(letter);
}
else
{
n = c - 97;
letter = key[n];
return tolower(letter);
}
}
else
{
return c;
}
}
【问题讨论】:
-
您需要用
'\0'终止ctxt,仅此而已。与strlen无关。 -
您还需要
char ctxt[n+1];为空字节留出空间。 -
您希望
printf知道要打印多少个字符?您如何期望strlen知道数组的长度?当事情没有按照您的预期进行时,首先要看的是为什么您预期会有不同的行为以及您的预期是否合理。 -
@Barmar,已经试过了 - 没有任何改变。
-
如果你不明白它是如何工作的,你需要回到你的教科书/教程并重新阅读关于字符串的章节。
标签: arrays c string cs50 strlen