如何忽略scanf中的浮点数(“%d”)?

如何忽略scanf中的浮点数(“%d”)?,c,scanf,C,Scanf,如果用户输入整数变量的浮点数,我想打印无效的输入。可能吗 int a; scanf("%d",&a); // if user enters 4.35 print invalid input 我试过这样的角色 if(scanf("%d",&a)==1); else printf("invalid input"); 但是如何处理浮点数呢。如果用户输入4.35,它将截断为4,但我希望输入无效 由于小数点之前有任何数字的浮点数的开头看起来像一个整数,因此仅用%d无法检测

如果用户输入整数变量的浮点数,我想打印无效的输入。可能吗

 int a;
 scanf("%d",&a); // if user enters 4.35 print invalid input 
我试过这样的角色

  if(scanf("%d",&a)==1);
  else printf("invalid input");

但是如何处理浮点数呢。如果用户输入
4.35
,它将截断为
4
,但我希望输入无效

由于小数点之前有任何数字的浮点数的开头看起来像一个整数,因此仅用
%d
无法检测到这一点

你可以考虑用<代码> fgScript()/<代码>读取整行,然后用<代码> sScCff()/<代码>:

进行分析。 (是的,我的意思是与1比较;
%n
转换规范不计入
sscanf()
等的返回值。)


scanf()
做的一件事是在输入数字之前跳过空行,而本代码没有做这件事。如果这很重要,您必须编写一个循环以读取(非空)行,然后解析非空行。您还需要确定在线上可以容忍多少拖尾垃圾(如果有)。允许空白吗?标签?字母字符?标点符号?

你必须把它读作双精度,然后检查它是否是整数。检查它是否为整数的最佳方法是使用,它返回双精度的小数部分。如果存在一个错误:

double d;
scanf("%lf", &d);

double temp;
if(modf(d, &temp)){
  // Handle error for invalid input
}

int a = (int)temp;

这将允许在小数点后仅包含
0
s的整数或浮点数,例如
54.00000
。如果你想把它看成是无效的,那么最好是按字符读取字符并验证每个字符都在<代码> 0 < /C>和<代码> 9 < /> >(ASCII 48到57)。 经典成语

char buf[100];
if (fgets(buf, sizeo(buf), stdin) == NULL) {
  ; // deal with EOF or I/O error
}
int a;
char ch;
if (1 != sscanf(buf, "%d %c", &a, &ch)) {
  ; // Error: extra non-white space text
}

这个比较简单:

#include <stdio.h>

int main() 
{
    int a;
    long double b;

    scanf("%f",&b);
    a = (int) b;

    a == b ? printf("%d\n",a) : printf("Invalid input!");

    return 0;
} 
输入:4.35
输出:

 Invalid input
这里有一个简单的方法:

#include <stdio.h>

int main(int argc, char **argv) {
    int d;
    printf("Type something: ");

    // make sure you read %d and the next one is '\n'
    if( scanf("%d", &d) == 1 && getchar() == '\n' ) {
        printf("%d\n", d);
    }

    return 0;
}

首先,
scanf
没有什么问题。当用户输入一个浮点数时,他们实际上会输入一个数字。因此,编写一个scanf来检测数据输入

main()
  {
       char c1[2];
       int num1;

       int nr_nums;

       nr_nums = scanf("%d%1[.e0123456789]", &num1, &c1);

       if (nr_nums == 1) {printf("\ndata = %d", num1);}
       if (nr_nums == 2) {printf("\nInvalid");}

 }
根据另一种可能的数据输入格式1修改了此代码。或评论中建议的3e-1


这段代码可以了解您的基本需求。它接受整数数据输入,并在输入浮点时进行检测。

您可以使用
strtol()
strtod()
并比较端点指针,例如:

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

int main(void) {
    char buffer[100];
    char * endptr_n;
    char * endptr_d;
    long n;
    double d;

    fgets(buffer, 100, stdin);
    n = strtol(buffer, &endptr_n, 10);
    if ( endptr_n == buffer ) {
        fputs("You didn't enter a number.", stderr);
        return EXIT_FAILURE;
    }

    d = strtod(buffer, &endptr_d);

    if ( *endptr_d == '\0' || *endptr_d == '\n' ) {
        if ( endptr_d == endptr_n ) {
            puts("You entered just a plain integer.");
        } else {
            puts("You entered a floating point number - invalid.");
        }
    } else {
        puts("You entered garbage after the number - invalid.");
    }

    return EXIT_SUCCESS;
}
它不使用
scanf()
,但这是一件好事,它避免了手动检查读取的整数后面的输入

显然,如果线上唯一的东西是数字,那么很多事情就变得不必要了,因为你可以直接调用
strtol()
并立即检查
*endptr\n
,但是如果线上可能有其他东西,这就是你可以做的,例如,如果你想接受一个整数后跟任何非数字,但不是后跟相同内容的浮点,您只需删除
if(*endptr_d='\0'|*endptr_d=='\n')
逻辑即可


编辑:更新代码以显示对
*endptr

的检查。如果您将数字表示为字符串(当您使用fgets时),则可以在其中运行for循环,并将每个字符与“.”进行比较。

我可以看到的另一个选项如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{

 char mystring[31];
 scanf("%30s[0-9]\n", mystring);
 int mynumber = atoi(mystring);
 printf("here is your integer: %d", mynumber);
 getchar();
 getchar();
 return 0;











 }
#包括
#包括
#包括
int main()
{
char mystring[31];
scanf(“%30s[0-9]\n”,mystring);
int mynumber=atoi(mystring);
printf(“这是您的整数:%d”,mynumber);
getchar();
getchar();
返回0;
}

可能会加入一个浮点数,然后检查四舍五入后是否保持不变?再次链接:我认为是相关帖子。这不是有点过于复杂了吗?这取决于你想要什么。使用
fgets()
sscanf()
通常优于
scanf()
;报告用户以这种方式键入的内容将更容易。因此,将其从解决方案中排除。这就留下了
sscanf(第%d%n行,&a和&n)=1
,并检查您是否没有小数点(默认值
,但通常是特定于语言环境的),或
e
e
作为下一个字符;任何其他内容都表示输入的值是整数。即使是
E
也不是严格证明;您需要查看
E
和一个数字。1.2E是数字1.2,后面有一个E,AFAIK(尽管我今天没有测试它)。有趣的是:在Ubuntu 12.04的派生版本上,下面的代码将
E
视为浮点数的一部分;它打印出空间(32)作为停止点<代码>#include int main(void){char data[]=“34.1E和junk”;double d;int n;if(sscanf(data,“%lf%n”,&d,&n)!=1)printf(“扫描失败”);else printf(“获取:%f(停止在“%c”%d)\n”,d,data[n],data[n]);返回0;我不完全相信这是正确的行为;在Mac OS X上,转换会在
E
上停止(根据我的推测是正确的)。(
“34.1E-和junk”
在Linux上也会在空白处停止。)实际上,在C99之前,未指定是否将
%n
的匹配计算在返回值中,因此在某些系统上成功匹配可能会返回2。这没关系,因为您可以通过使用
sscanf(第%d%n行,&a,&n)>=1来轻松捕捉这种情况,因为匹配失败将始终返回0。@C中的JH健壮I/O非常复杂!如果
d
int
范围之外,不需要检查范围吗?在许多64位机器上,64位范围的
int
超过了双精度,因此将不正确的值扫描到“a”中。长双精度
也可以工作。没有多少64位机器使用64位
int
大小;它让您在如何处理32位整数(或16位整数)方面左右为难。但是,如果您处理的是
long
(或64位
long
),则您的观点完全正确。@Jonat
main()
  {
       char c1[2];
       int num1;

       int nr_nums;

       nr_nums = scanf("%d%1[.e0123456789]", &num1, &c1);

       if (nr_nums == 1) {printf("\ndata = %d", num1);}
       if (nr_nums == 2) {printf("\nInvalid");}

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

int main(void) {
    char buffer[100];
    char * endptr_n;
    char * endptr_d;
    long n;
    double d;

    fgets(buffer, 100, stdin);
    n = strtol(buffer, &endptr_n, 10);
    if ( endptr_n == buffer ) {
        fputs("You didn't enter a number.", stderr);
        return EXIT_FAILURE;
    }

    d = strtod(buffer, &endptr_d);

    if ( *endptr_d == '\0' || *endptr_d == '\n' ) {
        if ( endptr_d == endptr_n ) {
            puts("You entered just a plain integer.");
        } else {
            puts("You entered a floating point number - invalid.");
        }
    } else {
        puts("You entered garbage after the number - invalid.");
    }

    return EXIT_SUCCESS;
}
paul@local:~/src/c$ ./testint
2
You entered just a plain integer.
paul@local:~/src/c$ ./testint
2.3
You entered a floating point number - invalid.
paul@local:~/src/c$ ./testint
3e4
You entered a floating point number - invalid.
paul@local:~/src/c$ ./testint
4e-5
You entered a floating point number - invalid.
paul@local:~/src/c$ ./testint
423captainpicard
You entered garbage after the number - invalid.
paul@local:~/src/c$
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{

 char mystring[31];
 scanf("%30s[0-9]\n", mystring);
 int mynumber = atoi(mystring);
 printf("here is your integer: %d", mynumber);
 getchar();
 getchar();
 return 0;











 }