【问题标题】:tolower() function problemstolow() 函数问题
【发布时间】:2012-09-09 08:23:08
【问题描述】:

这是我的示例代码:

#include<stdio.h>
#include<string.h>
#include<ctype.h>

void convert(char *a, char *b) {
    int i;
    for(i=0; i<strlen(a); i++) {
        b[i]=tolower(a[i]);
    }
}

int main() {
    char a[20], b[20];

    fgets(a, sizeof(a), stdin);
    convert(a, b);
    printf("%s\n", b);
    return 0;
}

但有时 convert() 函数也会比 strlen(a) 多转换一个字符(它是一个随机字符),例如这是一个输出:

ASDSA
asdsa
%

我该如何解决?

【问题讨论】:

  • 不是每次都处理多余的字符吗?
  • 你没有终止输出字符串。
  • 试试char a[20], b[20] = { 0 }

标签: c unix tolower


【解决方案1】:

您必须在b 的末尾添加一个空字符('\0')。

【讨论】:

    【解决方案2】:

    正如其他人提到的,您需要以空值结尾的目标字符串。除此之外,请注意您在循环的每次迭代中重新计算 a 的长度。这对于小字符串无关紧要,但对于大字符串,您会注意到转换时间与字符串长度的平方成正比。标准的成语是计算一次长度并重复使用。通过这两个更改,函数将如下所示:

    void convert(const char *a, char *b) {
        size_t i, len = strlen(a);
        for(i = 0; i < len; i++) {
            b[i] = tolower((unsigned char) a[i]);
        }
        b[len] = '\0';
    }
    

    【讨论】:

    • 为了防止未定义的行为,您应该将tolower 的参数转换为unsigned char。详情请见pubs.opengroup.org/onlinepubs/9699919799/functions/tolower.html
    • @RolandIllig 很好,我已经更新了答案。 (C99 还要求 tolower 参数为 EOF 或可表示为 unsigned char 的值,因此这不仅仅是 POSIX 的事情。)但这还不够,修改后的代码仍然包含潜伏的未定义行为:如果 a[i] 是负数,tolower((unsigned char) a[i]) 将返回一个会溢出char 的值。我没有检查标准,但希望可以通过将b 转换为unsigned char * 来避免这种情况,例如((unsigned char *)b)[i] = tolower((unsigned char) a[i])(或更易读的版本)。
    【解决方案3】:

    strlen 返回字符串的长度,例如 strlen("hello") 为 5。 这不会复制用于终止字符串的 0 字符(这意味着内存中的字符串实际上是 6 个字符长:'h' 'e' 'l' 'l' 'o' '0')

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-22
      • 2021-01-03
      • 2011-04-17
      相关资源
      最近更新 更多