将C字符串传递给返回C字符串指针的函数

Win*_*Key 1 c string pointers

我想传递一个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;
}
Run Code Online (Sandbox Code Playgroud)

chq*_*lie 5

您的代码中存在多个问题:

  • main应该有原型int main(void)一个好的风格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;
}
Run Code Online (Sandbox Code Playgroud)

如果您无法使用<ctype.h>,请使用此便携版本:

char *lower(char *s) {
    for (char *p = s; *p != '\0'; p++) {
        if (*p >= 'A' && *p <= 'Z')
            *p += 'a' - 'A';
    }
    return s;
}
Run Code Online (Sandbox Code Playgroud)