c-在scanf中,我怎么能忽略两个字符中的一个,但不能同时忽略两个



我对C还很陌生,我正在编写一些代码,允许用户以dd/mm/yyyy或dd-mm-yyyy的形式输入日期。我不知道如何让scanf忽略破折号或斜线,但不能同时忽略两者。输入斜线后,我需要代码来识别负数。目前,程序只是认为这是一个破折号,并忽略了它

    int dd1, mm1, yyyy1;
    char str [3];
    scanf("%d %[-/] %d %[-/] %d", &dd1, str, &mm1, str, &yyyy1);

任何帮助都将不胜感激!

您只需读取输入,然后使用sscanf()进行解析示例程序:

#include <stdio>
int main(void)
{
  char buf[256];
  int dd1, mm1, yyyy1;
  printf("input date: ");
  // this is normally a function for file operations, but if you define stdin,
  // the standard input, as file pointer it reads keyboard input
  fgets(buf, 256, stdin); 
  if(sscanf(buf, "%d-%d-%d", &dd1, &mm1, &yyyy1) != 3)
  {
    if(sscanf(buf, "%d/%d/%d", &dd1, &mm1, &yyyy1) != 3)
    {
      printf("Wrong format!n");
    }
    else
    {
      printf("format with /n");
    }
  }
  else
  {
    printf("Format with -n");
  }
}

好的,首先用fgets((读取输入。它将从标准输入(即键盘(中最多读取255个字节,并将其安全地放入我称为"buf"的数组中。然后我们使用sscan((来"分析"输入。sscanf()返回成功分配的变量数,因为您希望从字符串中读取3个数字,每个与3不同的返回值都表示错误/错误输入。第一个sscanf()-检查日期格式,第二个sscanf()/检查日期格式

对之前的事情感到抱歉。

如果你不想使用中间存储器,你可以让你的程序说"嘿!首先,我想要一个数字,然后是一个字符,然后是另一个数字、一个字符、最后是一个数字。"这正是你的日期字符串的格式。

还有两个条件,即,您希望中间的两个字符彼此相同,并且可以是短划线或斜杠。这就是你可以做到的:

int dd1, mm1, yyyy1;
char sep1, sep2;
if ( scanf( "%d%c%d%c%d", &dd1, &sep1, &mm1, &sep2, &yyyy1 ) == 5 && sep1 == sep2 && ( sep1 == '/' || sep1 == '-' ) )
    printf( "Day: %dnMonth: %dnYear: %d", dd1, mm1, yyyy1 );
else {
    // invalid syntax
}

正如我上面描述的那样,它要求一个整数,然后是一个字符、整数、字符和整数。如果它不能得到所有这些,那么它就不会返回5(scanf返回它填充的变量数(。接下来要检查两个分隔符是否相同;最后,分隔符必须是短划线或斜线。

只要把它作为一种替代,总会有另一种方法。

读取(潜在敌对(用户输入的经典方法包括3个步骤:

  1. I/O
  2. 正在分析
  3. 范围验证

I/O:

char buffer[100];
if (fgets(buffer, sizeof buf, stdin) == NULL) Handle_EOForIOerror();

分析

int dd1, mm1, yyyy1;
// check the result of `sscanf()`
if (sscanf(buffer, "%2d/%2d/%4d", &dd1, &mm1, &yyyy1) != 3) ||
    sscanf(buffer, "%2d-%2d-%4d", &dd1, &mm1, &yyyy1) != 3)) FormatError();

距离验证

if (dd1 < 1 || dd1 > 31 || mm1 < 1 || mm1 > 12 || ...) Handle_RangeError();

其他检查包括

1( 寻找尾随垃圾

int n;
if (sscanf(buffer, "%2d/%2d/%4d %n", &dd1, &mm1, &yyyy1, &n) != 3) ||
    sscanf(buffer, "%2d-%2d-%4d %n", &dd1, &mm1, &yyyy1, &n) != 3))FormatError();
if (buffer[n] != '') TrailingJunkDetected();

2( if (!valid_date(yyyy1, mm1, dd1)) ...

你可以试试这个:

scanf(" %3d%1[/-]%3d%1[/-]%5d", ...);

因为这些字段宽度只指定最大宽度,而没有指定最小宽度,所以它们不能用于区分窄字段的输入。因此,如果要严格限制输入格式为dd/mm/yyyydd-mm-yyyy,则需要在scanf()成功返回后进行更多语法检查。

这里有一个测试程序:

#include <stdio.h>
int
main(void)
{
    int yy, mm, dd;
    char del1[2], del2[2];
    const char *dates[] = {
        /* well formed */
        "28-03-2014",
        "-28-03-2014",
        "28--03-2014",
        "28-03--2014",
        "28/03/2014",
        "-28/03/2014",
        "28/-03/2014",
        "28/03/-2014",
        /* ill formed */
        "28-3-2014",
        "8-03-2014",
        "28-03-14",
        "28-03/2014",
        "28/03-2014",
        "28 03 2014",
        NULL,
    };
    for (size_t i = 0; dates[i]; i++) {
        int ret = sscanf(dates[i], " %3d%1[/-]%3d%1[/-]%5d", &dd, del1, &mm, del2, &yy);
        if (ret != 5 || del1[0] != del2[0]) {
            fprintf(stderr, "%s : syntax errorn", dates[i]);
            continue;
        }
        printf("del = %c, yy = %d, mm = %d, dd = %dn", del1[0], yy, mm, dd);
    }
    return 0;
}

相关内容

  • 没有找到相关文章

最新更新