在输入中获取整数而不会遇到任何错误
Get an integer in input without encountering any bugs
scanf()
肯定是个问题多多的函数,所以一直在找方法替代它。
我在 this post 的第一个答案中找到了这段代码,但即使这段代码也有问题(如果用户输入换行符,循环就会结束)。
有没有办法在输入中获取整数而不会遇到任何类型的错误?
代码:
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));
编辑:
我根据@chqrlie 的回答和我在 [此处][2] 找到的一段代码编写了这个函数,有什么方法可以改进这个函数并让它变得更好吗?
int readInteger(const char *prompt, const char *error) {
int number;
char buf[1024]; // use 1KiB to be sure
while(1) {
printf("%s", prompt);
if(!fgets(buf, 1024, stdin)) exit(1); // reading input failed
// have some input, convert it to integer
char *endptr;
errno = 0;
number = (int)strtol(buf, &endptr, 10);
while(isspace((unsigned char)*endptr)) endptr++; // ignore trailing white space
if(errno == ERANGE) printf("%s", error);
else if(endptr != buf && !(*endptr && *endptr != '\n')) return number;
}
}
发布的代码需要一些改进,但可以包装在函数中以读取 int
值:
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
int get_int(const char *prompt, int *result) {
char buf[100];
char *end;
for (;;) {
if (prompt) {
printf("%s: ", prompt);
}
if (!fgets(buf, sizeof buf, stdin)) {
printf("unexpected end of file\n");
return -1;
}
errno = 0;
long n = strtol(buf, &end, 0);
if (end == buf) {
printf("invalid input: %s", buf);
continue;
}
if (errno != 0 || n > INT_MAX || n < INT_MIN) {
printf("value outside range of int: %s", buf);
continue;
}
// ignore trailing white space
while (isspace((unsigned char)*end) {
end++;
}
if (*end != '[=10=]') {
printf("ignoring tailing input: %s", end);
}
*result = (int)n;
return 0; // success
}
}
scanf()
肯定是个问题多多的函数,所以一直在找方法替代它。
我在 this post 的第一个答案中找到了这段代码,但即使这段代码也有问题(如果用户输入换行符,循环就会结束)。
有没有办法在输入中获取整数而不会遇到任何类型的错误?
代码:
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));
编辑:
我根据@chqrlie 的回答和我在 [此处][2] 找到的一段代码编写了这个函数,有什么方法可以改进这个函数并让它变得更好吗?int readInteger(const char *prompt, const char *error) {
int number;
char buf[1024]; // use 1KiB to be sure
while(1) {
printf("%s", prompt);
if(!fgets(buf, 1024, stdin)) exit(1); // reading input failed
// have some input, convert it to integer
char *endptr;
errno = 0;
number = (int)strtol(buf, &endptr, 10);
while(isspace((unsigned char)*endptr)) endptr++; // ignore trailing white space
if(errno == ERANGE) printf("%s", error);
else if(endptr != buf && !(*endptr && *endptr != '\n')) return number;
}
}
发布的代码需要一些改进,但可以包装在函数中以读取 int
值:
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
int get_int(const char *prompt, int *result) {
char buf[100];
char *end;
for (;;) {
if (prompt) {
printf("%s: ", prompt);
}
if (!fgets(buf, sizeof buf, stdin)) {
printf("unexpected end of file\n");
return -1;
}
errno = 0;
long n = strtol(buf, &end, 0);
if (end == buf) {
printf("invalid input: %s", buf);
continue;
}
if (errno != 0 || n > INT_MAX || n < INT_MIN) {
printf("value outside range of int: %s", buf);
continue;
}
// ignore trailing white space
while (isspace((unsigned char)*end) {
end++;
}
if (*end != '[=10=]') {
printf("ignoring tailing input: %s", end);
}
*result = (int)n;
return 0; // success
}
}