如果用户为整数变量输入浮点数,我想打印无效输入。那可能吗?
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
,但我想要无效输入。
答案 0 :(得分:11)
由于小数点前的任何数字的浮点数的开头看起来像一个整数,因此无法单独使用%d
检测到这一点。
您可以考虑使用fgets()
阅读整行,然后使用sscanf()
进行分析:
int a;
int n;
char line[4096];
if (fgets(line, sizeof(line), stdin) != 0 && sscanf(line, "%d%n", &a, &n) == 1)
...analyze the character at line[n] for validity...
(是的,我的意思是与1进行比较; %n
转换规范不会计入sscanf()
等的返回值。
scanf()
执行此操作的一件事是在输入数字之前跳过空白行。如果这很重要,你必须编写一个循环来读取(非空)行,然后解析非空行。您还需要确定线路上有多少尾随垃圾(如果有的话)。是否允许空白?标签?阿尔法字符?标点?
答案 1 :(得分:4)
您必须将其作为双精度读取,然后检查它是否为整数。检查它是否为整数的最佳方法是使用modf,它返回double的小数部分。如果有,则表示您有错误:
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
和9
之间(ascii 48到57)。
答案 2 :(得分:3)
这不能通过读取int
来查看停止扫描的内容。
经典成语
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
}
答案 3 :(得分:2)
您可以使用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;
}
输出:
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$
它不使用scanf()
,但这是一件好事,它避免了在您读取的整数之后手动检查输入的需要。
显然,如果线路上唯一的东西是数字,那么很多事情就变得没必要,因为你可以立即拨打strtol()
并立即检查*endptr_n
,但是如果有其他东西的话这就是你如何做到这一点,例如如果你想接受一个整数后跟任何非数字的整数,但不是一个浮点然后是同一个东西,你可以删除if ( *endptr_d == '\0' || *endptr_d == '\n' )
逻辑。
编辑:更新了代码以显示对*endptr
的检查。
答案 4 :(得分:1)
这个更简单:
#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
输出:
4
输入:4.35
输出:
Invalid input
答案 5 :(得分:1)
这是一个简单的方法:
#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;
}
$ a.exe
Type something: 312312.4214
$ a.exe
Type something: 2312312
2312312
$ a.exe
Type something: 4324.
$
答案 6 :(得分:1)
首先,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。
此代码了解您的要求的基础知识。它接受Integer数据输入并检测何时输入浮点数。
答案 7 :(得分:0)
如果您将数字表示为字符串(当您使用了fgets时),您可以运行for循环并将每个字符与'。'进行比较。
答案 8 :(得分:-1)
我可以看到的另一个选择如下:
#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;
}