CLion 建议使用 'strtol' 而不是 'scanf'

问题描述 投票:0回答:2
#include <stdio.h>

int main(int argc, char** argv) {
    int num = 0;

    printf("Input: ");
    scanf("%d", &num); <<<

    printf("%d\n", num);

    return 0;
}

scanf("%d", &num);

Clang-Tidy:'scanf'用于将字符串转换为整数值,但函数不会报转换错误;考虑改用“strtol”


我用 CLion 写了一个非常简单的代码,它建议我使用“strtol”而不是“scanf”。

但我只使用整型变量,没有字符串。我想不通为什么会弹出检查消息。

如何修改此代码?

c clion
2个回答
9
投票

如何修改此代码?

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>

enum { INPUT_SIZE = 30 };

int main () {
    char *ptr;
    long ret;
    char str[INPUT_SIZE];

    fgets(str, INPUT_SIZE, stdin);    
    ret = strtol(str, &ptr, 10);

    if( ret == LONG_MAX || ret == LONG_MIN ) {
        perror("!! Problem is -> ");
    }
    else if (ret) {
        printf("The number is %ld\n", ret);
    }
    else {
        printf("No number found input is -> %s\n", ptr);
    }

    return(0);
}

如果成功,

strtol()
返回转换后的long int值。

如果不成功,

strtol()
如果无法转换则返回
0
执行。如果正确的值超出了可表示的范围 值,
strtol()
返回
LONG_MAX
LONG_MIN
,根据符号 的价值。如果不支持base的值,
strtol()
回报
0
.

如果不成功

strtol()
将 errno 设置为以下值之一:

错误代码:

EINVAL 不支持base的值

ERANGE 转换导致溢出。 资料来源:IBM

你可以使用

scanf()
检查溢出吗?

Input:  1234 stackoverflow
Output: The number is 1234

Input:  123nowhitespace
Output: The number is 123

Input:  number is 123
Output: No number found input is -> number is 123

Input:  between123between
Output: No number found input is -> between23between

Input:  9999999999999999999
Output: !! Problem is -> : Result too large

也许偏离主题但是,Jonathan Leffler 在他的评论(在另一个主题中)中说处理警告就像错误一样。


0
投票

您收到的警告表明您正在使用

scanf
函数将字符串转换为整数值,但
scanf
不会 报告转换错误。相反,建议使用
strtol
函数,该函数旨在将字符串转换为整数,并且具有 更好的错误处理。

strtol
函数接受一个字符串作为输入并返回一个整数值。如果值超出范围,它还通过将
errno
变量设置为
ERANGE
来提供错误检查,如果存在转换错误,则通过将
endptr
设置为导致转换停止的字符。

这里是一个如何使用

strtol
将字符串转换为整数的例子:

#include <stdlib.h>
#include <stdio.h>

int main() {
    char str[] = "12345";
    char *endptr;
    long num = strtol(str, &endptr, 10);
    if (*endptr != '\0') {
        printf("Conversion error: %s\n", endptr);
    } else {
        printf("Number: %ld\n", num);
    }
    return 0;
}

在本例中,

strtol
函数用于将字符串“12345”转换为整数。 base 参数设置为 10 以指示该字符串表示十进制数。
endptr
参数是一个指向字符的指针,该字符将设置为字符串中无法转换为整数的第一个字符。如果整个字符串转换成功,
endptr
将被设置为空字符
'\0'
。如果存在转换错误,
endptr
将被设置为导致转换停止的字符。

使用

strtol
代替
scanf
可以帮助您编写更健壮的代码 更优雅地处理错误。

© www.soinside.com 2019 - 2024. All rights reserved.