c/c++语言开发共享scanf格式说明符,用于从一组字符中读取零个或多个字符

对于可以在读取字符串中的字符,我需要非常严格。

我有一系列的空格,后跟一个字符,后跟一系列空格。
示例: " c ""c"""" "

我需要找到一个格式说明符,允许我忽略该字符,但只有当它是这个特殊字符而不是任何其他字符时。 应该中止该序列" e "

我尝试了" %*[c] "但我的unit testing在某些情况下失败 – 让我相信" %*[c] "正在寻找一个或多个'c'而不是零或更多'c'

我写了一个小例子来帮助更好地说明我的问题。 请记住,这只是一个最小的例子。 核心问题是我如何解析零或一个单个字符的数量。

 #include  #include  unsigned match(const char * formula){ unsigned e = 0, found = 0, s; char del; int parsed, pos, len = (int) strlen(formula); const size_t soc = sizeof( char ); del = ' '; parsed = sscanf_s( formula, " " %*[(] X%*[^>]>> %u %*[)] %c %n", &s, &del, soc, &pos );// (X >> s ) if( ( 2 == parsed ) && ( pos == len) && ( '"' == del ) ){ printf("%6s:%sn", "OK", formula); }else{ printf("%6s:%sn", "FAIL", formula); e += 1; } return e; } unsigned main( void ) { unsigned e = 0; printf("SHOULD BE OKn"); e += match(" "X >> 3""); //This one does not feature the optional characters e += match(" "( X >> 3 ) ""); e += match(" "( X >> 3 ) "r"); printf("SHOULD FAILn"); if ( 0 == match(" "( Y >> 3 ) "") ) e += 1; if ( 0 == match(" "g X >> 3 ) "") ) e += 1; if ( 0 == match(" "( X >> 3.3-4.2 ) "") ) e += 1; if( 0 != e ){ printf( "ERRORS: %2un", e ); } else{ printf( "all passn", e ); } return e; } 

    正如其他人向您指出的那样,不建议使用sscanf 。 它无法捕获的情况是“可选” (可能会或可能不会出现在"X "之间。对于scanf ,如果有一个可选字段没有任何类型的分隔符来表示它丢失,那么确定它缺失的唯一方法是尝试解析它,注意它不存在,并尝试使用不同的扫描格式字符串再次解析它。

     parsed = sscanf( formula, " " %*[(] X%*[^>]>> %u %*[)] %c %n", &s, &del, &pos ); if (parsed != 2) { parsed = sscanf( formula, " " X%*[^>]>> %u %c %n", &s, &del, &pos ); } 

    本解决方案的其余部分描述了如何使用POSIX 基本正则表达式来解析它。

    首先,您需要定义正则表达式并进行编译。

     const char *re = "[ t]*"" /* match up to '"' */ "[ t]*(\{0,1\}[ t]*" /* match '(' if present */ "X[ t]*>>[ t]*" /* match 'X >>' */ "\([0-9][0-9]*\)" /* match number as subexpression */ "[ t]*)\{0,1\}[ t]*" /* match ')' if present */ "\(.\)" /* match final delimiter as subexpression */ "[ trn]*"; /* match trailing whitespace */ regex_t reg; int r = regcomp(&reg, re, 0); if (r != 0) { char buf[256]; regerror(r, &reg, buf, sizeof(buf)); fprintf(stderr, "regcomp: %sn", buf); /*...*/ } 

    现在,您需要针对要匹配的字符串执行表达式。 编译器将跟踪正则表达式中的子表达式的数量,并将该数字放在reg.re_nsub 。 但是,有一个隐含的子表达式不包含在该计数中。 这是与提供的表达式匹配的完整字符串。 这总是出现在第一场比赛中。 因此,当您创建匹配的数组时,请考虑到这一点。 这就是为什么matches数组比reg.re_nsub matches数组多一个。

     unsigned match(const regex_t *preg, const char * formula){ /*...*/ int r; const int NSUB = preg->re_nsub + 1; regmatch_t matches[NSUB]; r = regexec(preg, formula, NSUB, matches, 0); if (r == 0) { /* success */ parsed = preg->re_nsub; s = atoi(formula + matches[1].rm_so); del = formula[matches[2].rm_so]; pos = matches[0].rm_eo; } else { parsed = 0; } /*...*/ 

    完成正则表达式后,应该释放它(如果它已成功编译)。

     regfree(&reg); 

      以上就是c/c++开发分享scanf格式说明符,用于从一组字符中读取零个或多个字符相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/c-cdevelopment/544709.html

      (0)
      上一篇 2021年1月9日
      下一篇 2021年1月9日

      精彩推荐