如何使用scanf正确解析和过滤动态输入?

如何使用scanf正确解析和过滤动态输入?,c,scanf,C,Scanf,这是家庭作业,所以我坚持我描述的要求 我需要处理以下一般形式的输入: XYZ A1 5 第一部分(XYZ)是命令,A1是地址(我只需要1),而5是命令的值。此外,我需要处理既没有地址也没有值的命令(例如,只有XYZ),以及只有地址但没有值的命令(XYZ A1) 我设法将胶带粘在一起,似乎能很好地处理一切咳嗽: n = scanf("%c%c%c A%i %i",&c1,&c2,&c3,&a,&val); 因此,我可以使用n(有多少个参数/变量scanf

这是家庭作业,所以我坚持我描述的要求

我需要处理以下一般形式的输入:

XYZ A1 5
第一部分(
XYZ
)是命令,
A1
是地址(我只需要1),而
5
是命令的值。此外,我需要处理既没有地址也没有值的命令(例如,只有
XYZ
),以及只有地址但没有值的命令(
XYZ A1

我设法将胶带粘在一起,似乎能很好地处理一切咳嗽:

n = scanf("%c%c%c A%i %i",&c1,&c2,&c3,&a,&val);
因此,我可以使用
n
(有多少个参数/变量
scanf
能够匹配)来确定它是什么类型的命令,然后进行一些基本检查以获得我需要的。而且它工作得很好

但我的问题是: 还有一个格式为
XYZ A1 A2
的命令,因为它有两个“地址”值。如何让
scanf
也解析这个?再一次,我真的不需要解析“A”

如果我这样做:

scanf("%c%c%c A%i A%i",&c1,&c2,&c3,&a,&val);
然后,当地址和值输入前面没有“A”时,其他各种命令将不起作用


p.S.不允许使用任何形式的字符串/数组,因此使用字符


我能在这里做什么

解决方案是使用scanf(“%c%c%ca%i%c%i”、&c1、&c2、&c3、&A、&c4、&val),检查c4是否是一个数字,在这种情况下,您需要做更多的工作来获得正确的val,但不是很多。

解决方案是使用
scanf(“%c%c%c%a%i%c%i”、&c1、&c2、&c3、&a、&c4、&val),检查c4是否是一个数字,在这种情况下,您需要做更多的工作来获得正确的val,但不是很多。

不要试图在一次
scanf
调用中完成这一切。相反,首先读取命令,检查它是否需要其他参数,然后读取这些参数:

n = scanf( "%c%c%c", &c1, &c2, &c3 );
if ( n != 3 )
  // input error, bail out here

if ( has_address( c1, c2, c3 ) )
{
  if ( scanf( "A%i", &a1 ) != 1 )
    // input error, bail out here
}

if ( has_2nd_address( c1, c2, c3 ) )
{
  if ( scanf( "A%i", &a2 ) != 1 )
    // input error, bail out here
}

if ( has_value( c1, c2, c3 ) )
{
  if ( scanf( "%i", &val ) != 1 )
    // input error
}

的has_address
的has_address
的has_value
只是占位符,用于确定是否需要读取一个或两个地址,以及是否需要读取值

不要试图在一次
scanf
调用中完成所有操作。相反,首先读取命令,检查它是否需要其他参数,然后读取这些参数:

n = scanf( "%c%c%c", &c1, &c2, &c3 );
if ( n != 3 )
  // input error, bail out here

if ( has_address( c1, c2, c3 ) )
{
  if ( scanf( "A%i", &a1 ) != 1 )
    // input error, bail out here
}

if ( has_2nd_address( c1, c2, c3 ) )
{
  if ( scanf( "A%i", &a2 ) != 1 )
    // input error, bail out here
}

if ( has_value( c1, c2, c3 ) )
{
  if ( scanf( "%i", &val ) != 1 )
    // input error
}

的has_address
的has_address
的has_value
只是占位符,用于确定是否需要读取一个或两个地址,以及是否需要读取值

检查返回值。如果是4,则最后一个数字仍需扫描

// Add leading space to consume previous line's \n
int n = scanf(" %c%c%c A%i A%i", &c1, &c2, &c3, &a, &val);

switch (n) {
  case 5: Handle_XYZ_A1_A2(c1, c2, c3, a, val); break;
  case 4: // A not detected
    int n = scanf("%i", &val);
    if (n == 1) { Handle_XYZ_A1_2(c1, c2, c3, a, val); break; }
  default:
    Handle_Bad_Input();
}

首先使用
fgets()
更有意义,但在给定操作限制的情况下似乎不允许使用。

检查返回值。如果是4,则最后一个数字仍需扫描

// Add leading space to consume previous line's \n
int n = scanf(" %c%c%c A%i A%i", &c1, &c2, &c3, &a, &val);

switch (n) {
  case 5: Handle_XYZ_A1_A2(c1, c2, c3, a, val); break;
  case 4: // A not detected
    int n = scanf("%i", &val);
    if (n == 1) { Handle_XYZ_A1_2(c1, c2, c3, a, val); break; }
  default:
    Handle_Bad_Input();
}

首先使用
fgets()
更有意义,但鉴于操作限制,似乎不允许这样做。

我建议使用
fgets
读取输入,然后应用
sscanf
。然后,当您请求的3个字段中只有2个字段存在时,很容易忽略该行的其余部分并转到下一个字段。在分析输入的所有字符串之前,扫描三个字符串。使用
sscanf
中的函数返回值。您还可以对最后一个使用
%s
,然后解析该字符串(如果存在)。但这是使用字符串/数组,上述解决方案也是如此。或者,您可以使用
%c%i
作为最后一个字符,并检查第一个字符是什么。Guysss请完整阅读文章-不允许使用任何形式的数组,包括字符串。虽然我会查看Weather Vane的第一个解决方案,但这可能是正确的,因为它仍然使用某种扫描,谢谢!“不允许使用任何形式的字符串”-->注意:
%c%c A%i A%i“
是一个字符串。您需要能够从输入中读取一系列这样的指令,还是只需要处理一个?因为运行循环中的
scanf()
不会达到预期效果。尾随空格(例如换行符)将使其出错。我建议使用
fgets
读取输入,然后应用
sscanf
。然后,当您请求的3个字段中只有2个字段存在时,很容易忽略该行的其余部分并转到下一个字段。在分析输入的所有字符串之前,扫描三个字符串。使用
sscanf
中的函数返回值。您还可以对最后一个使用
%s
,然后解析该字符串(如果存在)。但这是使用字符串/数组,上述解决方案也是如此。或者,您可以使用
%c%i
作为最后一个字符,并检查第一个字符是什么。Guysss请完整阅读文章-不允许使用任何形式的数组,包括字符串。虽然我会查看Weather Vane的第一个解决方案,但这可能是正确的,因为它仍然使用某种扫描,谢谢!“不允许使用任何形式的字符串”-->注意:
%c%c A%i A%i“
是一个字符串。您需要能够从输入中读取一系列这样的指令,还是只需要处理一个?因为运行循环中的
scanf()
不会达到预期效果。尾随空格(如换行符)会使它出错。真不敢相信我没有想到这一点,谢谢!!真不敢相信我竟然没有想到,谢谢!!