我希望用户只输入两个整数,但不能超过两个或少于两个。此外,在无效输入时,我希望打印错误并提示用户再次输入两个整数。用户应输入由空格分隔的两个整数,而不是换行符。因此,例如:
1)有效输入为:1 2
2)输入无效:1
3)输入无效:1 2 3
我尝试了以下两种方法:
#include<stdio.h>
int main(){
int first;
int second;
printf("Enter input:\n");
int returnValue = scanf("%d %d", &first, &second);
while(returnValue != 2){
printf("Invalid input. Please enter again: \n");
returnValue = scanf("%d %d", &first, &second);
}
printf("First: %d Second: %d\n", first, second);
return 0;
}
在涉及scanf的第一种方法中,我无法阻止用户在换行符上输入每个整数。我也不能将输入限制为仅2个数字。也就是说,如果用户输入的整数超过2个,则程序接受前2个整数并忽略第3个整数。我想在那种情况下打印错误。
我的另一种方法涉及fgets和sscanf:
#include<stdio.h>
int main(){
int first;
int second;
printf("Enter input:\n");
char line[20];
fgets(line, sizeof(line), stdin);
int returnValue = sscanf(line, "%d %d", &first, &second);
while(returnValue != 2){
printf("Invalid input. Please enter again: \n");
fgets(line, sizeof(line), stdin);
returnValue = sscanf(line, "%d %d", &first, &second);
}
printf("First: %d Second: %d\n", first, second);
return 0;
}
在这种方法中,如果用户在输入一个整数后命中输入,我就能够打印错误。但我无法将输入限制为仅2个数字。也就是说,如果用户输入的整数超过2个,则程序接受前2个整数并忽略第3个整数。我想在那种情况下打印错误。
所以我的问题是,通过修改第一种方法和第二种方法,我的要求是否可以实现?
感谢。
答案 0 :(得分:3)
一种解决方案是在两次success: function(data) {
$('#partial').html(data);
}
次转化后使用%n
转换规范。 %d
转换规范与任何字符都不匹配,但会在格式字符串中存储读取到此点的字符数。所以,在电话中:
%n
如果达到第二个sscanf(line, "%d %d %n", &first, &second, &bufPos);
,则%d
将保留bufPos
中读取的最后一个字符后的字符索引。由于line
之前有空格,因此在将索引值存储到%n
之前,将读取并跳过零个或多个空白字符。因此,在有效输入后,bufPos
将指示bufPos
终止符。如果在此索引的\0
中找到任何其他字符,则输入中会出现无关的字符。
以下是您的第二个代码示例的修改版本。在line
读取输入行后,fgets()
用于扫描字符串。如果匹配次数少于2次,或者sscanf()
不是line[bufPos]
,则'\0'
设置为badInput
。输入循环是true
循环,只执行一次,只要do
为badInput
,就会继续执行。
true
示例互动:
#include <stdio.h>
#include <stdlib.h> // for exit()
#include <stdbool.h> // for bool type
#define BUF_SIZE 100
int main(void)
{
int first;
int second;
char line[BUF_SIZE];
int returnValue;
int bufPos;
bool badInput = false;
do {
if (badInput) {
printf("Invalid input. Please enter again: ");
badInput = false;
} else {
printf("Enter input: ");
}
if (fgets(line, sizeof(line), stdin) == NULL) {
perror("Error in fgets()");
exit(EXIT_FAILURE);
}
returnValue = sscanf(line, "%d %d %n", &first, &second, &bufPos);
if (returnValue < 2 || line[bufPos] != '\0') {
badInput = true;
}
} while (badInput);
printf("First: %d Second: %d\n", first, second);
return 0;
}
答案 1 :(得分:1)
要在char *
提出要求时防止出现问题,您可以使用regular expression。
如果你没有被迫得到二合一scanf
,你可以使用这个功能:
int secure_input(int max, int min) {
int choice,buffer;
do {
choice = -1;//initialize in a values not included among min and max
scanf("%d", &choice);
while ((buffer = getchar()) != '\n' ? buffer != EOF : false); // empty the buffer to avoid infinite loop
} while (choice > max ? true : choice < min);
return choice;
}
在你的主要功能中你只需要调用这个函数:
first = secure_input(2;1);
答案 2 :(得分:0)
与其他答案不同,您还可以使用strtok()
解析输入,然后检查找到的数量。这种方法很复杂,但它确实提供了对问题的不同看法。
在while()
循环中,您可以查看fgets()
中找到的间隔号码数,如果只找到2
,那么您可以break
环。否则,继续搜索。一旦退出循环,那么您可以从最近的输入读取中sscanf()
两个整数。您还可以使用strtol()
检查整数是否有效。
注意: strtok()
是reeantrant,它确实修改了它解析的字符串。所以在这种情况下,您可能需要在某处创建它的副本。您可以使用strdup()
或malloc()
执行此操作。
以下是一些示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LINESIZE 20
#define BASE 10
int main(void) {
char line[LINESIZE];
const int n = LINESIZE;
char *number, *copy, *endptr;
const char *delim = " ";
int first, second, check, invalidnum;
size_t slen, count;
while (1) {
printf("Enter input: ");
if (fgets(line, n, stdin) == NULL) {
printf("Error reading buffer from fgets()\n");
exit(EXIT_FAILURE);
}
slen = strlen(line);
if (slen > 0 && line[slen-1] == '\n') {
line[slen-1] = '\0';
} else {
printf("Buffer overflow detected\n");
exit(EXIT_FAILURE);
}
copy = strdup(line);
count = 0;
invalidnum = 0;
number = strtok(copy, delim);
while (number != NULL) {
check = strtol(number, &endptr, BASE);
if (endptr == number || check == 0) {
invalidnum = 1;
break;
}
count++;
number = strtok(NULL, delim);
}
free(copy);
copy = NULL;
if (count != 2 || invalidnum) {
printf("Invalid input\n\n");
} else {
break;
}
}
if (sscanf(line, "%d %d", &first, &second) != 2) {
printf("Unexpected error from sscanf()\n");
exit(EXIT_FAILURE);
}
printf("first = %d, second = %d\n", first, second);
return 0;
}
这只是解决问题的另一种方法。在简单性方面,@ David Bowling有更好的主意,我建议使用他的。