[英]Using sscanf to validate a string input
在 Java 和 Python 编码后,我刚刚开始学习 C。
我想知道如何“验证”一个字符串输入(如果它符合某个标准),我偶然发现了sscanf()
function。
我的印象是它的行为类似于正则表达式,但是我不太清楚如何用它创建相当复杂的查询。
例如,假设我有以下字符串:
char str[]={"Santa-monica 123"}
我想使用sscanf()
检查字符串中是否只有字母、数字和破折号。
有人可以详细说明吗?
sscanf
允许看起来有点像字符 class 的事实绝不意味着它完全像正则表达式库。 事实上,Posix 甚至不需要scanf
函数来接受字符类中的字符范围,尽管我怀疑它在您将遇到的任何实现上都可以正常工作。
但是您遇到的扫描问题也不需要正则表达式。 您所需要的只是一个重复的字符 class 匹配, sscanf
当然可以做到这一点:
#include <stdbool.h>
bool check_string(const char* s) {
int n = 0;
sscanf(s, "%*[-a-zA-Z0-9]%n", &n);
return s[n] == 0;
}
scanf 格式背后的想法是,第一次转换将匹配并丢弃由有效字符组成的最长初始序列。 (如果第一个字符无效,它可能会失败。感谢@chux 指出。)如果成功,它会将n
设置为当前扫描点,即下一个字符的偏移量。 如果下一个字符是 NUL,那么所有字符都是好的。 (此版本对空字符串返回 OK,因为它不包含非法字符。如果您希望空字符串失败,请将返回条件更改为return n && s[n] == 0;
)
您也可以使用标准正则表达式库(或任何更复杂的库,如果您愿意,但 Posix 库通常无需额外工作即可使用)来执行此操作。 这需要更多的代码来编译正则表达式。 为了提高效率,以下尝试只编译一次正则表达式,但为了简单起见,我省略了同步以避免初始化期间的数据竞争,因此不要在多线程应用程序中使用它。
#include <regex.h>
#include <stdbool.h>
bool check_string(const char* s) {
static regex_t* re_ptr = NULL;
static regex_t re;
if (!re_ptr) regcomp((re_ptr = &re), "^[[:alnum:]-]*$", REG_EXTENDED);
return regexec(re_ptr, s, 0, NULL, 0) == 0;
}
我想使用
sscanf()
检查字符串中是否只有字母、数字和破折号。
@rici的变化很好的答案。
为字母、数字和破折号创建一个扫描集。
//v The * indicates to scan, but not save the result.
// v Dash (or minus sign), best to list first.
"%*[-0-9A-Za-z]"
// ^^^^^^ Letters a-z, both cases
// ^^^ Digits
使用"%n"
来检测扫描的距离。
现在我们可以使用确定
由于null 字符导致扫描停止(整个字符串有效)
由于无效字符而停止扫描
int n = 0;
sscanf(str, "%*[-0-9A-Za-z]%n", &n);
bool success = (str[n] == '\0');
sscanf
没有此功能,您所指的参数是格式说明符,不用于验证。 见这里: https://www.tutorialspoint.com/c_standard_library/c_function_sscanf.htm
正如还提到的sscanf
用于不同的工作。 有关更多信息,请参阅此链接。 您可以使用isalpha
和isdigit
遍历字符串以检查字符串中的字符是否为数字和字母字符。
char str[]={"Santa-monica 123"}
for (int i = 0; str[i] != '\0'; i++)
{
if ((!isalpha(str[i])) && (!isdigit(str[i])) && (str[i] != '-'))
printf("wrong character %c", str[i]);//this will be printed for spaces too
}
我想...检查字符串中是否只有字母、数字和破折号。
在 C 中,传统上使用isalnum (3) 和朋友完成。
bool valid( const char str[] ) {
for( const char *p = str; p < str + strlen(str); p++ ) {
if( ! (isalnum(*p) || *p == '-') )
return false;
}
return true;
}
您也可以使用友好的邻居正则表达式(3),但您会发现需要大量代码才能进行简单扫描。
在 sscanf() 上检索值后,您可以使用正则表达式来验证该值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.