【问题标题】:CLion recommends to use 'strtol' instead of 'scanf'CLion 建议使用“strtol”而不是“scanf”
【发布时间】:2018-06-11 09:55:24
【问题描述】:
#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


【解决方案1】:

如何修改此代码?

#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_MAXLONG_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 在他的 cmets(在另一个主题中)说 将警告作为错误处理。

【讨论】:

  • 不初始化可以使用ptr吗?
  • @NBlizz NULL 可以通过那里。但是,char * 传递有助于查看输入的内容。输入123 teststring作为输入后,123作为数字,teststring作为ptr。如果输入的开头不包含数字,则应用后者。
  • @NBlizz the code snippet 来查看您的长尺码。在我的机器中是 8,这意味着长存储在 -9,223,372,036,854,775,8079,223,372,036,854,775,807 之间。您不需要检查 LONG_MIN 或 MAX,因为它们是符合每台机器的别名。您可以通过上述链接,代码 sn-p 尝试超出长限制。
  • @snr 我还是不明白为什么会发出这样的警告?
猜你喜欢
  • 1970-01-01
  • 2015-01-11
  • 1970-01-01
  • 1970-01-01
  • 2015-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-16
相关资源
最近更新 更多