我正在用C编写一个程序,它接受用户输入的任何一种格式:
有效输入的一些例子:
我如何用C来完成这个任务?
下面是我到目前为止掌握的代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
int main()
{
char name[10];
int num1;
int num2;
if(scanf("%s %d", name, &num1) != 2 || scanf("%s %d %d", name, &num1, &num2) != 3)
{
printf("Failure");
}
else
{
printf("Pass");
}
}这将打印"Failure“(如果有无效的用户输入)和"Pass”(如果用户输入有效)。这里的问题是,这段代码迫使我输入两种格式,以便打印“Pass”。因此,如果我输入"Susan 5“,我将不得不输入"David 1024”,以便打印"Pass“,即使我有一个或有条件的,而不是一个和条件的,这我不明白。我想要的是一旦我输入"Susan 5“并点击enter,我的程序应该能够打印”Pass“。
发布于 2021-10-30 19:13:36
如果我正确理解你的问题,有三种可能的输入:
一个单词后面跟着一个整数
由于您已经在注释部分中指出,在第2种情况下,将第二个整数存储为浮点数是可以接受的,所以我们可以将第2和第3种情况视为相同的情况。
排在队伍里
if(scanf("%s %d", name, &num1) != 2 || scanf("%s %d %d", name, &num1, &num2) != 3)第二个scanf函数调用可能无法工作,因为第一个函数已经消耗了部分输入。因此,您应该首先使用fgets读取一行输入,并将对scanf的调用替换为对sscanf的调用
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char name[10];
int num1;
double num2;
char line[100];
int num_consumed;
//attempt to read one line of input
if ( fgets( line, sizeof line, stdin ) == NULL )
{
fprintf( stderr, "input error!\n" );
exit( EXIT_FAILURE );
}
//verify that entire line was read in
if ( strchr( line, '\n' ) == NULL )
{
fprintf( stderr, "line too large for input buffer!\n" );
exit( EXIT_FAILURE );
}
//attempt to convert first two parameters
if ( sscanf( line, "%9s%d%n", name, &num1, &num_consumed ) != 2 )
{
printf( "Failure\n" );
return 0;
}
printf( "Pass\n" );
//attempt to read third parameter as a floating-point number
if ( sscanf( line+num_consumed, "%lf", &num2 ) != 1 )
{
printf( "User entered only one number:\n%d\n", num1 );
}
else
{
printf( "User entered two numbers:\n%d\n%f\n", num1, num2 );
}
}此程序具有以下行为:
输入错误:
Susan David
Failure只有一个数字作为输入:
Susan 5
Pass
User entered only one number:
5两个整数作为输入:
David 10 24
Pass
User entered two numbers:
10
24.000000一个整数和一个浮点数作为输入:
Sarah 6 7.5
Pass
User entered two numbers:
6
7.500000程序的一个可能问题是它不检查第二个sscanf失败的原因。例如,它将处理输入
Susan 5 dslfhksdhfkl
与用户输入的内容相同:
Susan 5
这个问题并没有说明在这种情况下输入是否应该打印Failure。但是,同时在注释部分中,您已经声明程序应该拒绝输入,例如:
Susan 5 ddggghh
David 10 24 dslfhksdhfkl因此,在下面的程序中,我在这两种情况下都添加了一个额外的检查,以验证匹配字符之后的所有剩余字符都是空白字符 (至少在行尾总会有一个换行符)。如果没有,则输入将被拒绝。
为了确定一个字符是否是空白字符,我使用函数isspace。
在这里,使用这些附加检查更新的程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdbool.h>
//this function will return whether a string consists
//entirely of whitespace characters
bool is_string_whitespace( const char *str )
{
for ( const char *p = str; *p != '\0'; p++ )
{
if ( !isspace( (unsigned char)*p ) )
return false;
}
return true;
}
int main()
{
char name[10];
int num1;
double num2;
char line[100], *p;
int num_consumed;
//attempt to read one line of input
if ( fgets( line, sizeof line, stdin ) == NULL )
{
fprintf( stderr, "input error!\n" );
exit( EXIT_FAILURE );
}
//verify that entire line was read in
if ( strchr( line, '\n' ) == NULL )
{
fprintf( stderr, "line too large for input buffer!\n" );
exit( EXIT_FAILURE );
}
//attempt to convert first two parameters
if ( sscanf( line, "%9s%d%n", name, &num1, &num_consumed ) != 2 )
{
printf( "Failure\n" );
return 0;
}
//attempt to read third parameter as a floating-point number
p = line + num_consumed;
if ( sscanf( p, "%lf%n", &num2, &num_consumed ) == 1 )
{
//verify that all remaining characters are whitespace
if ( !is_string_whitespace( p+num_consumed ) )
{
printf( "Failure" );
return 0;
}
printf( "Pass\n" );
printf( "User entered two numbers:\n%d\n%f\n", num1, num2 );
}
else
{
//verify that all remaining characters are whitespace
if ( !is_string_whitespace( p ) )
{
printf( "Failure" );
return 0;
}
printf( "Pass\n" );
printf( "User entered only one number:\n%d\n", num1 );
}
}该程序现在正确地拒绝了上述输入:
Susan 5 dslfhksdhfkl
FailureDavid 10 24 dslfhksdhfkl
Failurehttps://stackoverflow.com/questions/69780894
复制相似问题