如何解决从'long'到有符号类型'char'的缩小转换是实现定义的C中的strtol函数
我正在尝试使用 strtol 将输入的字符转换为整数。这是源代码的一部分:
char option;
char *endptr;
printf("=========================================Login or Create Account=========================================\n\n");
while(1) {
printf("Welcome to the Bank management program! Would you like to 1. Create Account or 2. Login?\n>>> ");
fgets(&option,1,stdin);
cleanStdinBuffer();
option = strtol(&option,&endptr,10);
在 strtol 函数中,我收到一条警告:
Clang-Tidy: Narrowing conversion from 'long' to signed type 'char' is implementation-defined
谁能告诉我我做错了什么?
解决方法
Clang-Tidy 警告您关于您在此处执行的隐式转换,您将 long
的 strtol
返回值分配给 char
:
option = strtol(&option,&endptr,10);
如果这是故意的,并且您确定该值将在 [-128,127] 范围内,这不一定是一个问题(这只是一个警告),但即便如此,我还是建议您显式转换strtol
,使用 int8_t
代替 char
,并且不要将 option
变量重用于返回值。换句话说:
int8_t value = (int8_t)strtol(&option,10);
如果不是故意的,我建议您简单地使用 long
作为您分配 strtol 返回值的变量的类型,因此:
long value = strtol(&option,10);
Clang-tidy 没有警告您的是 strtol
的第一个参数应该是指向包含以 0 结尾的字符串的字符缓冲区的指针,而不是指向单个字符的指针。这也是 fgets 的问题。有两种方法可以解决这个问题:
-
使选项成为至少包含两个字符的
char
数组, -
改用 fgetc 并将您的代码修改为如下所示:
int option = fgetc(stdin); if (option == '1') { /*Create Account */ } else if (option == '2') { /* Login */ } else { /* Error */ }
我认为后者看起来更干净。
,char
只能保存 long
值的很小子集。 strtol 返回 long
并将其分配给 char
。
这个 fgets 调用
fgets(&option,1,stdin);
始终将字符 option
设置为终止零字符 '\0'
,前提是用户没有中断输入。
这是一个演示程序。
#include <stdio.h>
int main(void)
{
char c = 'A';
printf( "Before calling fgets c = %d\n",c );
fgets( &c,stdin );
printf( "After calling fgets c = %d\n",c );
return 0;
}
程序输出为
Before calling fgets c = 65
After calling fgets c = 0
与用户将输入的内容无关。这里的值 65
是在调用 'A'
之前存储在变量 c 中的字符 fgets
的 ASCII 码。
如果你想输入一个字符,那么你应该使用
scanf( " %c",&input );
注意转换说明符前的空格。
此调用后,您可以检查用户是否输入了类似的数字
#include <ctypes.h>
//...
if ( isdigit( ( unsigned char )input ) ) input = input - '0';
并将变量输入设置为[0,9]
范围内相应的整数值。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。