如何将 tolower() 与 char 数组一起使用?

How do I use tolower() with a char array?

我在学校学习 C 并正在做一些输入和字符串比较,并且 运行 遇到了一个看起来像转换的问题。

这是我的代码:

size_t unit_match_index(char *userInput) {
    char* unit = malloc(strlen(userInput) + 1);
    strcpy(unit, userInput);
    
    //convert to lowercase
    for (size_t i = 0; i < strlen(unit); ++i) {
        unit[i] = tolower(unit[i]);
    /*C6385: invalid data from 'unit': the readable size is 'strlen(userInput)+1' bytes, but 2bytes may be read
      C6386: buffer overrun while writing to 'unit': the writable size is [same as above]
    */
    }
//...
}

经过一些研究,看起来 tolower() 寻找一个 int 和 returns 一个 int(2 个字节),并认为 strlen(userInput)+1 可能等同于 1,使得总的单位数组大小只有 1 个字节。

我应该做些什么来避免这种情况,或者这只是分析仪是一台计算机(计算机是愚蠢的)?我很担心,因为如果有错误,我的作业会被扣分。

正如 的回答中所建议的那样,这两个警告是由 MSVC 代码分析器中的“错误”引起的。

我什至尝试了我在回答该问题时建议的 'fix'(即使用 char* unit = malloc(max(strlen(userInput), 0) + 1);)——但它在您的代码中不起作用(不确定原因)。

然而,所做的工作(我不知道为什么)是在适当的地方使用strdup函数您对 mallocstrcpy 的调用 – 它做同样的事情,但一举成名。

添加评论中建议的转换(正确)1,这是您的代码版本,不会生成虚假的 C6385 和 C6386 警告:

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

size_t unit_match_index(char* userInput)
{
    char* unit = strdup(userInput);
    //convert to lowercase
    for (size_t i = 0; i < strlen(unit); ++i) {
        unit[i] = (char)tolower((unsigned char)unit[i]);
    }
    //...
    return 0;
}

但是,MSVC 现在将生成一个不同的(但同样是虚假的)警告:

warning C4996: 'strdup': The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name: _strdup. See online help for details.

碰巧,the strdup function没有前导下划线)自C23(6/2019)起被采纳为ISO标准的一部分。


1 关于使用tolower函数时强制转换的原因,参见:Do I need to cast to unsigned char before calling toupper(), tolower(), et al.?。但是,简单地添加这些转换 不会 消除两个代码分析警告。