简体   繁体   English

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

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

I'm learning C in school and am doing some input and string comparisons and am running into what looks like a casting issue.我正在学校学习 C 并且正在做一些输入和字符串比较,并且遇到了看起来像铸造问题的问题。

Here is my code:这是我的代码:

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]
    */
    }
//...
}

After doing a little bit of research, it looks like tolower() looks for an int and returns an int (2 bytes), and thinks strlen(userInput)+1 may equate to 1 , making the total unit array size only 1 byte.经过一番研究,看起来tolower()寻找一个int并返回一个int (2 个字节),并认为strlen(userInput)+1可能等于1 ,使得总单元数组大小只有 1 个字节。

Is there something I should be doing to avoid this, or is this just the analyzer being a computer (computers are dumb)?我应该做些什么来避免这种情况,或者这只是分析仪是一台计算机(计算机是愚蠢的)? I'm concerned because I will lose marks on my assignment if there are errors.我很担心,因为如果有错误,我的作业会被扣分。

As suggested in an answer to this related question , these two warnings are caused by a "bug" in the MSVC Code Analyser.正如对这个相关问题的回答所建议的那样,这两个警告是由 MSVC 代码分析器中的“错误”引起的。

I even tried the 'fix' I suggested in my answer to that question (that is, using char* unit = malloc(max(strlen(userInput), 0) + 1); ) – but it didn't work in your code (not sure why).我什至尝试了我在回答该问题时建议的“修复”(即使用char* unit = malloc(max(strlen(userInput), 0) + 1); )——但它在您的代码中不起作用(不知道为什么)。

However, what did work (and I have no idea why ) is to use the strdup function in place of your calls to malloc and strcpy – it does the same thing but in one fell swoop.但是,起作用的是(我不知道为什么是使用strdup function 代替您对mallocstrcpy的调用 - 它做同样的事情,但一举一动。

Adding the casts (correctly) 1 suggested in the comments, here's a version of your code that doesn't generate the spurious C6385 and C6386 warnings:添加评论中建议的演员表(正确) 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;
}

However, MSVC will now generate a different (but equally spurious) warning:但是,MSVC 现在会生成一个不同的(但同样是虚假的)警告:

warning C4996: 'strdup': The POSIX name for this item is deprecated.警告 C4996:“strdup”:不推荐使用此项目的 POSIX 名称。 Instead, use the ISO C and C++ conformant name: _strdup.而是使用符合 ISO C 和 C++ 的名称:_strdup。 See online help for details.详细信息请参见在线帮助。

As it happens, the strdup function ( without the leading underscore) is adopted as part of the ISO Standard since C23 (6/2019).碰巧的是,自 C23 (6/2019) 以来, strdup function不带前导下划线)作为 ISO 标准的一部分被采用。


1 On the reasons for the casts when using the tolower function, see: Do I need to cast to unsigned char before calling toupper(), tolower(), et al.? 1关于使用tolower function 时出现强制转换的原因,请参阅:在调用 toupper()、tolower() 等之前是否需要强制转换为无符号字符? . . However, simply adding those casts does not silence the two code analysis warnings.但是,简单地添加这些强制转换不会使两个代码分析警告静音。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM