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

时间:2017-07-13 19:45:14

标签: 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;
}

2 个答案:

答案 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指针的东西 - 在其他操作中使用它 - 例如作为另一个函数调用中的参数。