我有使用sscanf
一个简单的程序。我遇到的问题是,匹配%[^-]s
后,sscanf
似乎只是停止匹配。
下面是简单的代码,明白我的意思。 %s
后%[^-]s %s
比赛完全忽略。
注:我需要%[^-]s
因为我需要我的程序同时匹配可能的字符串。
注2:我知道代码是完全不安全等,这只是一个例子!
#include <stdio.h>
int main(void) {
int matches;
int num1, num2, num3, num4;
char *s1[10];
char *s2[10];
char *s3[40];
char *s4[50];
char *s5[50];
char *s6[50];
char *s7[50];
char fileTest[] = "29 0 8:4 / / rw,relatime shared:1 - ext4 /dev/sda4 rw,errors=remount-ro";
// char fileTest[] = "160 48 179:56 /inte /var/oil/gaol/org.something.org/media/internal ro,nosuid,relatime - ext4 /dev/mmccc rw,data=ordered";
matches = sscanf(fileTest, "%d %d %d:%d %s %s %[^-]s %s",
&num1, &num2, &num3, &num4, s1, s2, s3, s4);
printf("matches: %d\n", matches);
printf("num1: %d\n", num1);
printf("num2: %d\n", num2);
printf("num3: %d\n", num3);
printf("num4: %d\n", num4);
printf("s1: %s\n", s1);
printf("s2: %s\n", s2);
printf("s3: %s\n", s3);
printf("s4: %s\n", s4);
return 0;
}
需要注意的是s
扫描设置后%[…]
是字面s
,而不是扫描集的一部分。在上下文中,%[^-]s
永远比不上s
,所以任何下列转换失败。该%[^-]
部分吃掉任何不是一个破折号-
(和s
不是-
,所以它得到chomped,用空格和其他事情一样),那么s
不匹配(因为转换停止在-
或字符串的结尾),所以扫描失败那里和最终%s
从不匹配。
见sscanf()
的POSIX规范。阅读。重读它。重新再读一遍。再重新再读一遍。今天!而同样的明天。您可以缩减到一天两次一周的休息,那么一旦一个星期,每天和每周一次一个月,然后每月一次为今年余下时间,一年至少一次之后。函数的scanf()
家庭可能是最困难的标准C函数使用得很好。
有你的代码的其他重大问题。特别是,char *s1[10];
应char s1[10];
,并且类似地对于其它的阵列。或者你需要经过重大演习中的分配空间的阵列指向等。而且,正如你可能知道,%s
(和%[^-]
)转换不限制的输入。使用%9s
或%49[^-]
等,适当的大小。参见How to prevent scanf()
causing a buffer overflow in C?
格式说明,直到遇到一个%[^-]
-
匹配的一切;所以有此相匹配后,在缓冲区中的下一个字符要检查的格式字符串是-
(如果有的话)。但是,如果你让这个模式遵循s
,即%[^-]s
,那么什么都不会匹配任何更多,因为-
永远不匹配格式字符串所需s
。
有你的代码中的多个问题:
sscanf
格式是%[chars]
或%[^chars]
,有s
之后没有拖尾]
。在你的榜样,sscanf()
将尝试在第三个字符串后匹配s
和失败,防止后续%s
的转换。s1
通过s4
应char
阵列,不char *
的阵列。%[^-]
停止在-
或输入字符串的末尾,通过%s
解析过去的字符串将是-
或match
计数将反映不存在-
隔板。如果你想输入的其余部分,你应该使用%[^\n]
这里是一个修正版本:
#include <stdio.h>
int main(void) {
int matches;
int num1, num2, num3, num4;
char s1[10], s2[10], s3[40], s4[50];
char fileTest[] = "29 0 8:4 / / rw,relatime shared:1 - ext4 /dev/sda4 rw,errors=remount-ro";
// char fileTest[] = "160 48 179:56 /inte /var/oil/gaol/org.something.org/media/internal ro,nosuid,relatime - ext4 /dev/mmccc rw,data=ordered";
matches = sscanf(fileTest, "%d %d %d:%d %9s %9s %39[^-] - %49[^\n]",
&num1, &num2, &num3, &num4, s1, s2, s3, s4);
printf("matches: %d\n", matches);
printf("num1: %d\n", num1);
printf("num2: %d\n", num2);
printf("num3: %d\n", num3);
printf("num4: %d\n", num4);
printf("s1: %s\n", s1);
printf("s2: %s\n", s2);
printf("s3: %s\n", s3);
printf("s4: %s\n", s4);
return 0;
}
输出:
matches: 8
num1: 29
num2: 0
num3: 8
num4: 4
s1: /
s2: /
s3: rw,relatime shared:1
s4: ext4 /dev/sda4 rw,errors=remount-ro