arrays - 为什么在 For 循环中数组不填充值,其中每个数组元素 [i] 都分配有变量?
问题描述
代码编译正常。我尝试使用调试器,但无法找出问题所在。每次迭代“c”都被填充,但似乎我尝试将此变量“c”分配到数组中的方式没有任何反应,因此结束打印语句以“ciphertext:EMPTY NOTHING”结束
非常欢迎任何帮助或想法。我正在学习课程并尝试解决一组问题。我只是初学者,请不要努力:)
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
int main (int argc, string argv[])
{
if(argc < 2 || argc<2 )
{
printf("Usage: ./caesar key \n");
return 1;
}
else if(argc == 2)
{
for (int i = 0; i < strlen(argv[1]); i++)
{
if(!isdigit(argv[1][i]))
{
printf("Usage: ./caesar key \n");
return 1;
}
}
}
int key = atoi(argv[1]);
string initial_text = get_string("plaintext: ");
int cipher[strlen(initial_text)];
int i = 0;
int n = strlen(initial_text);
for (i = 0; i < n; i++)
{
int c = 0;
if (isupper(initial_text[i]))
{
c = (((int)initial_text[i] - 65 + key) % 26) + 65;
cipher[i] += c;
}
else if (islower(initial_text[i]))
{
c = (((int)initial_text[i] - 97 + key) % 26) + 97;
cipher[i] += c;
}
else
{
c=initial_text[i];
cipher[i] += c;
}
}
//////////////////
printf("ciphertext: %c\n", (char)cipher);
}
解决方案
有很多问题:
- 当您 [可能] 需要时使用
int
for 。cipher
char
cipher
没有为尾随的 0x00 [EOS] 字符串终止符定义足够的空间- 最后没有设置EOS。
- 在
%c
你%s
的printf
. if ((argc < 2) || (argc < 2))
是错误的,可以替换为if (argc != 2)
.- 因为这样
if
做了,所以不再需要return
后续检查。else if
- “硬连线”十进制值(例如
65
for'A'
)。 - 在循环
strlen
中的条件表达式中使用。for
这将循环的运行时间从 O(n) 增加到 O(n^2)。 - 这可以替换为(例如)将数组元素与 0x00 进行比较。
- 使用
strtol
代替atoi
和检查结束可以在单个操作中进行解码和验证。 string
定义时不要使用argv
--usechar **argv
。- 你最后
main
缺少一个return 0;
。 - 有很多可以简化的复制代码。
这是重构的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
// I don't have cs50 handy, so a quick hack ...
#define string char *
string
get_string(const char *prompt)
{
char buf[1000];
char *cp;
printf("%s",prompt);
fflush(stdout);
do {
cp = fgets(buf,sizeof(buf),stdin);
if (cp == NULL)
break;
// strip newline
buf[strcspn(buf,"\n")] = 0;
// IIRC, [real] get_string does heap allocation (vs. static buffer) but
// for demo purposes here, doesn't really matter
cp = strdup(buf);
} while (0);
return cp;
}
int
main(int argc, char **argv)
{
// check if there is exactly 2 arguments passing, otherwise prompt for a
// valid key(+return 1, to signal mistake)
if (argc != 2) {
printf("Usage: ./caesar key \n");
return 1;
}
// otherwise check if the key is only a digit and prompt for a valid
// key(+return 1, to signal mistake)
// loop through each character in the second argument and validate
char *arg = argv[1];
// convert a string to int variable to be used in transformation of letters
int key = strtol(arg,&arg,10);
if (*arg != 0) {
printf("Usage: ./caesar key \n");
return 1;
}
// prompt for plaintext
string initial_text = get_string("plaintext: ");
// create an array of int to store encrypted letters to then be converted
// in print by (char)
// NOTE: we need one extra to make room for the trailing EOS
char cipher[strlen(initial_text) + 1];
const char *src = initial_text;
char *dst = cipher;
for (int chr = *src++; chr != 0; chr = *src++, ++dst) {
if (isupper((unsigned char) chr)) {
*dst = (((chr - 'A') + key) % 26) + 'A';
continue;
}
if (islower((unsigned char) chr)) {
*dst = (((chr - 'a') + key) % 26) + 'a';
continue;
}
// for all none alphabetic symbols leave them as they are
*dst = chr;
}
// set the trailing EOS
*dst = 0;
// ////////////////
printf("ciphertext: %s\n", cipher);
return 0;
}
推荐阅读
- html - 角度或html如何按条件显示模板
- r - 如何让 tinytex 在 rstudio 上生成 pdf?
- ios - 在嵌套对象上使用 for 循环
- javascript - Stack Navigator 抽屉图标单击抽屉未打开但滑动打开时
- javascript - 如何在 React Native 中集成 QuickBlox?
- javascript - JavaScript - 解析 json 对象时遇到问题
- c# - 在 Linq 中创建对象的新实例
- java - 尝试异步引导 Hibernate 时出现 Spring Boot 2.1.0 错误
- windows-installer - 使用 NSIS 卸载 windows 注册表项时,我们是否需要从 windows 注册表中删除每个条目?
- numpy - 通过广播对轴上的 np.minimum 和 np.minimum 进行矢量化