CS50 Pset2 Caesar:字符串转整数失败及类型转换错误求助
CS50 Caesar作业错误修复指南
核心错误解释:isdigit调用错误
你遇到的error cast to smaller integer type 'int' from 'string' (aka 'char *')错误,原因是isdigit()函数需要传入单个字符的ASCII值(int类型),但你传入的是整个字符串的指针argv[1](string本质是char*)。C编译器尝试把指针转换为int类型,而指针的字节长度通常比int长(比如64位系统中指针是8字节,int是4字节),因此触发类型不匹配的错误。
分步修复代码中的问题
1. 修复密钥合法性检查
遍历argv[1]的每个字符,检查是否都是数字:
for (int i = 0; i < strlen(argv[1]); i++) { // 转成unsigned char避免负数ASCII的问题 if (!isdigit((unsigned char) argv[1][i])) { printf("Usage: ./caesar [key]\n"); return 1; } }
2. 修复函数名不一致问题
你声明的函数是ciphertext,但调用时写成了cipher_text,统一函数名:
// 把调用行的cipher_text改成ciphertext ciphertext(plaintext, key);
3. 移除错误的printf语句
printf("Ciphertext: %s\n", ciphertext);这行错误,因为ciphertext是函数名,不是字符串变量。你的ciphertext函数直接打印加密后的字符,所以删掉这行,调用函数前先打印固定前缀即可。
4. 修复循环变量未声明问题
在ciphertext函数的for循环中,变量i未声明,需要加上int:
for (int i = 0; i < strlen(plaintext); i++)
5. 修复加密逻辑错误
原代码的((plaintext[i] + key) % 26) + 'a'逻辑错误,因为直接对字符ASCII值加key取模会超出范围。正确做法是先把字符转换为0-25的偏移量,再计算:
- 小写字母:
(plaintext[i] - 'a' + key) % 26 + 'a' - 大写字母:
(plaintext[i] - 'A' + key) % 26 + 'A'
另外,原代码的条件判断逻辑混乱,改成if-else if-else结构避免重复判断:
if (islower((unsigned char) plaintext[i])) { printf("%c", (plaintext[i] - 'a' + key) % 26 + 'a'); } else if (isupper((unsigned char) plaintext[i])) { printf("%c", (plaintext[i] - 'A' + key) % 26 + 'A'); } else { printf("%c", plaintext[i]); }
完整修正后的代码
#include <cs50.h> #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> void ciphertext(string plaintext, int key); int main(int argc, string argv[]) { if (argc == 2) { // 检查密钥是否为非负整数 for (int i = 0; i < strlen(argv[1]); i++) { if (!isdigit((unsigned char) argv[1][i])) { printf("Usage: ./caesar [key]\n"); return 1; } } int key = atoi(argv[1]); printf("Thank you. Key is %d\n", key); string plaintext = get_string("Plaintext: "); printf("Ciphertext: "); ciphertext(plaintext, key); printf("\n"); } else { printf("Usage: ./caesar [key]\n"); return 1; } return 0; } void ciphertext(string plaintext, int key) { for (int i = 0; i < strlen(plaintext); i++) { if (islower((unsigned char) plaintext[i])) { printf("%c", (plaintext[i] - 'a' + key) % 26 + 'a'); } else if (isupper((unsigned char) plaintext[i])) { printf("%c", (plaintext[i] - 'A' + key) % 26 + 'A'); } else { printf("%c", plaintext[i]); } } }
内容的提问来源于stack exchange,提问作者Donttalktome
相关产品推荐
相关产品推荐

