[英]C sscanf to validate input format
我想编写一个程序,它从用户那里读取一行输入,格式如下: <Name>,<Age>,<City>
-
。-
only。它们中的每一个都可以是 49 号。我想存储信息并打印一个信息性错误将打印错误输入。
我的代码如下:
char str[150];
char input[3][50] = { 0 };
int num = 0;
if (fgets(str, 150, stdin) != NULL) {
num = sscanf(str, "%[a-zA-Z -],%[0-9],%[a-zA-Z-]", input[0], input[1], input[2]);
}
if (num < 3) {
printf("ERROR\n");
}
问题是对于诸如Name1$#,20,NY
、 Best,19,Rome123
或Best,100,Paris1$
之类的输入不会打印错误,其中城市格式错误(带有尾随字符)。 有什么方法可以使用sscanf
解决它?
您可以根据需要使用sscanf()
和字符类,但格式字符串存在一些小问题:
AZ
采用 ASCII 编码或至少是字母连续的编码。-
具有特殊含义,将破折号放在第一个 position 以明确匹配破折号。 而不是使用fgets()
,您应该手动阅读该行以检测过长的行。
您可以添加额外的%c
以检查行尾的额外字符。 如果您不打算使用字段值,则不需要存储转换后的值,但您必须转换数字以检查其值是否在请求的范围内:
char str[150];
char name[50];
char city[50];
char agestr[4];
size_t i;
int c, age, pos, n;
for (i = 0; (c = getchar()) != EOF && c != '\n'; i++) {
if (i < sizeof(str) - 1)
str[i] = (char)c;
}
if (c == EOF && i == 0) {
printf("end of file\n");
return -1;
}
if (i >= sizeof(str)) {
printf("line too long\n");
return 0;
}
str[i] = '\0';
pos = 0;
/* validate the name */
if (sscanf(str + pos, "%49[-a-zA-Z ]%n", name, &n) != 1 || str[pos + n] != ',') {
printf("invalid name\n");
return 0;
}
pos += n + 1;
/* validate the age */
if (str[pos] == '0' || sscanf(str + pos, "%3[0-9]%n", agestr, &n) != 1 || str[pos + n] != ',') {
printf("invalid age\n");
return 0;
}
age = atoi(agestr);
if (age < 18 || age > 120) {
printf("age out of range: %d\n", age);
return 0;
}
pos += n + 1;
/* validate the city */
if (sscanf(str + pos, "%49[-a-zA-Z]%n", city, &n) != 1 || str[pos + n] != '\0') {
printf("invalid city\n");
return 0;
}
/* Input was validated... proceed */
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.