[英]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 代替您对malloc
和strcpy
的调用 - 它做同样的事情,但一举一动。
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.