我正在使用凯撒密码程序来弄脏手,但我仍然坚持使用以下代码:
char * encrypt(char *input) {
int length = strlen(input);
char *encrypted;
encrypted = malloc(length+1);
encrypted[0] = 0;
int i;
for(i=0; i < length; i++) {
printf("%c\n", input[i]);
if (i>0) {
encrypted[i] = input[i];
}
}
encrypted[length] = '\0';
printf("Encrypted: %s\n", encrypted);
return encrypted;
}
现在我只想弄清楚为什么我无法复制char的输入字符。末尾的加密字符串显示为空。 printf
的{{1}}语句会产生正确的值。
代码有什么问题?
答案 0 :(得分:2)
您没有复制字符串的第一个字符(在索引0处)。您可以将该字符设置为0(NUL),因此当您将encrypted
打印为字符串时,它看起来长度为零。
删除if (i>0)
测试并无条件地复制该字符。您还可以删除encrypted[0] = 0;
行,因为您要用字符串的第一个字符覆盖它。
答案 1 :(得分:1)
你已经得到了答案,只是为了详细说明期望部分,让我加上我的两分钱。
引用C11
,章节§7.21.6.1,对于%s
转换说明符,printf()
,预期的参数类型为
s
如果不存在
l
长度修饰符,则参数应为指向初始值的指针 字符数组的元素。数组中的字符是 写最多(但不包括)终止空字符。 [...]
因此,如果第一个元素为null,它就会停在那里。
换句话说,C风格的字符串的定义来自C11
,章节§7.1.1
字符串是由第一个空值终止并包含第一个空值的连续字符序列 字符。 [....]
所以,最重要的是,每当你使用一个你期望成为字符串的数组时,你需要确保
例如,根据定义,内容如“abc \ 0def \ 0”的数组是完全有效的字符串,但它可能不符合您的要求,因为“def”部分将是没有函数处理期望字符串,因为在此之前有一个空终止符并且它们在那里停止处理。
现在,在循环遍历每个元素时,您不再依赖于null-terminator,因此(只要您在数组范围内),您将获得所有单个元素的正确值。 / p>
答案 2 :(得分:0)
encrypted[0] = 0;
和if (i > 0) {
吗?
所以C风格的字符串输出函数不会打印任何字符串。
答案 3 :(得分:0)
if (i>0) {
encrypted[i] = input[i];
问题在这里,你的if应该是这样的
if (i>=0) {
encrypted[i] = input[i];
这个没有多大意义