如何scanf只有整数?
我希望代码运行直到用户输入整数值。
该代码适用于char和char数组。
我做了以下事情:
#include int main() { int n; printf("Please enter an integer: "); while(scanf("%d",&n) != 1) { printf("Please enter an integer: "); while(getchar() != '\n'); } printf("You entered: %d\n",n); return 0; }
问题是如果用户输入浮点值, scanf
将接受它。
Please enter an integer: abcd Please enter an integer: a Please enter an integer: 5.9 You entered: 5
怎么可以避免?
- 你拿
scanf()
。 - 你把它扔进垃圾箱。
- 你使用
fgets()
来获得整行。 - 您使用
strtol()
将该行解析为整数,检查它是否消耗了整行。
char *end; char buf[LINE_MAX]; do { if (!fgets(buf, sizeof buf, stdin)) break; // remove \n buf[strlen(buf) - 1] = 0; int n = strtol(buf, &end, 10); } while (end != buf + strlen(buf));
使用fgets
和strtol
,
指向s
整数表示后面的第一个字符的指针存储在p
指向的对象中,如果*p
与\n
不同则输入错误。
#include #include int main(void) { char *p, s[100]; int n; while (fgets(s, sizeof(s), stdin)) { n = strtol(s, &p, 10); if (p == s || *p != '\n') { printf("Please enter an integer: "); } else break; } printf("You entered: %d\n", n); return 0; }
我知道如何使用
fgets
和strtol
完成此操作,我想知道如何使用scanf()
(如果可能)来完成。
正如其他答案所说, scanf
并不适合这个, fgets
和strtol
是另一种选择(虽然fgets
的缺点是很难在输入中检测到0字节,并且在0之后无法确定输入的内容-byte,如果有的话)。
为了完整起见(假设有效输入是一个整数后跟换行符):
while(scanf("%d%1[\n]", &n, (char [2]){ 0 }) < 2)
或者,在%*1[\n]
之前和之后使用%n
和赋值抑制。 但请注意(来自Debian手册页 ):
这不是转换,尽管可以使用
*
赋值抑制字符来抑制它。 C标准说:“执行%n
指令不会增加执行完成时返回的赋值计数”,但勘误表似乎与此相矛盾。 可能明智的做法是不对%n
转换对返回值的影响做出任何假设。
尝试在scanf
使用以下模式。 它会一直读到行尾:
scanf("%d\n", &n)
由于scanf
将读取整行,因此您不需要循环内的getchar()
。 浮点数与scanf
模式不匹配,提示符将再次请求整数。
如果您已开始使用scanf
,则可以执行以下操作:
int val; char follow; int read = scanf( "%d%c", &val, &follow ); if ( read == 2 ) { if ( isspace( follow ) ) { // input is an integer followed by whitespace, accept } else { // input is an integer followed by non-whitespace, reject } } else if ( read == 1 ) { // input is an integer followed by EOF, accept } else { // input is not an integer, reject }
一个可能的解决方案是向后思考:接受float作为输入,如果float不是整数,则拒绝输入:
int n; float f; printf("Please enter an integer: "); while(scanf("%f",&f)!=1 || (int)f != f) { ... } n = f;
虽然这确实允许用户输入类似12.0或12e0等的内容。
使用fgets()
更好。
要仅使用scanf()
进行输入,请扫描int
和以下char
。
int ReadUntilEOL(void) { char ch; int count; while ((count = scanf("%c", &ch)) == 1 && ch != '\n') ; // Consume char until \n or EOF or IO error return count; } #include int main(void) { int n; for (;;) { printf("Please enter an integer: "); char NextChar = '\n'; int count = scanf("%d%c", &n, &NextChar); if (count >= 1 && NextChar == '\n') break; if (ReadUntilEOL() == EOF) return 1; // No valid input ever found } printf("You entered: %d\n", n); return 0; }
如果用户仅输入空白,例如仅输入,则此方法不会重新提示。