如何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 

怎么可以避免?

  1. 你拿scanf()
  2. 你把它扔进垃圾箱。
  3. 你使用fgets()来获得整行。
  4. 您使用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)); 

使用fgetsstrtol

指向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; } 

我知道如何使用fgetsstrtol完成此操作,我想知道如何使用scanf() (如果可能)来完成。

正如其他答案所说, scanf并不适合这个, fgetsstrtol是另一种选择(虽然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; } 

如果用户仅输入空白,例如仅输入,则此方法不会重新提示。