我正在尝试将C字符串(char*)
传递给函数lower(char *)
(如在原型中),它将C字符串char *lower()
返回到main()
。但我没有得到所需的输出。指出我的错误,并提出一些获得结果的技巧。
(注意:不允许使用<string.h>
个函数,并且必须使用指针完成任务)。这是我的代码,
#include <stdio.h>
#include <stdlib.h>
char *lower(char *);
void main() {
char pass[10], *pass1;
printf("Enter a password\n");
scanf("%s", pass);
pass1 = lower(pass);
printf("Lower case ");
int i = 0;
while (*pass1 != '\0') {
printf("%c", *(pass1 + i));
i++;
}
}
char *lower(char *p) {
while (*p != '\0') {
if (*p >= 'A' && *p <= 'Z') {
*p = *p + 32;
}
p++;
}
return p;
}
答案 0 :(得分:5)
您的代码中存在多个问题:
main
应该有原型int main(void)
a for good style在正文末尾有一个return 0;
语句。
scanf()
应通过指定要读入的最大字符数来保护目标数组不被溢出:scanf("%9s", pass);
,您应该检查其返回值是否成功转换。
您应该使用pass1[i]
代替*(pass1 + i)
。两个表达式都是等价的,但第一个更具可读性。顺便提一下,另一个同等但令人惊讶的替代方案是i[pass1]
,除非你想让读者感到困惑,否则不要使用它,这在密码处理程序中是可取的。
使用printf("%c", pass1[i])
打印单个字符似乎没有被发布的规则强制执行:使用单个printf
语句。
此外,循环测试是常量:while (*pass1 != '\0')
因为您只在循环中递增i
。因此,当您访问超出其结尾的pass
元素时,会出现无限循环和未定义的行为。
当您将返回值传递给printf()
时,函数lower()
应该返回原始指针,而不是指向参数字符串末尾的指针。
您不应该硬编码小写和大写字符之间的区别,32
仅适用于ASCII,而不适用于EBCDIC。 *p += 'a' - 'A';
将更具可移植性和可读性。它适用于ASCII和EBCDIC,但可能不适用于其他不太常见的字符集,并且测试if (*p >= 'A' && *p <= 'Z')
对于EBCDIC不够精确,因为大写字母不形成连续集。使用<ctype.h>
中的宏作为便携式解决方案。
以下是更正后的版本:
#include <stdio.h>
#include <ctype.h>
char *lower(char *);
int main(void) {
char pass[80];
printf("Enter a password\n");
if (scanf("%79s", pass) == 1) {
printf("Lower case: %s\n", lower(pass));
}
return 0;
}
char *lower(char *s) {
for (char *p = s; *p != '\0'; p++) {
*p = tolower((unsigned char)*p);
}
return s;
}
如果您无法使用<ctype.h>
,请使用此便携版本:
char *lower(char *s) {
for (char *p = s; *p != '\0'; p++) {
if (*p >= 'A' && *p <= 'Z')
*p += 'a' - 'A';
}
return s;
}
答案 1 :(得分:3)
char *lower(char *p){
char *ptr = p;
while(*p != '\0'){
if( *p>='A' && *p<='Z' ){
*p = *p + 32;
}
p++;
}
return ptr;
}
为什么有时返回类似转换的char指针的东西 - 在其他操作中使用它 - 例如作为另一个函数调用中的参数。