带有字符类的fscanf

时间:2012-10-28 23:25:03

标签: c

说我有一个文件dog.txt

The quick brown fox jumps over the lazy dog.

我可以从这个文件中读取

# include <stdio.h>
int main(){
  char str[10];
  FILE *fp;
  fp = fopen("dog.txt", "r");
  fscanf(fp, "%[ABCDEFGHIJKLMNOPQRSTUVWXYZ]", str);
  printf("%s\n", str);
  return 0;
}

,程序将输出T。但是,我可以使用POSIX字符类,而不是列出所有字母,例如[:upper:]吗?

3 个答案:

答案 0 :(得分:2)

不,你不能。这是您可以使用[]

执行的操作
  

转换规范包括格式字符串中的所有后续字节,包括匹配的&lt; right-square-bracket&gt; ( ']')。方括号( scanlist )之间的字节构成扫描集,除非&lt; left-square-bracket&gt;之后的字节。是一个&lt; circumflex&gt; ('^'),在这种情况下,扫描集包含未出现在&lt; right-square-bracket&gt;之间的扫描列表中的所有字节。如果转换规范以“[]”或“[^]”开头,则&lt; right-square-bracket&gt;包含在扫描列表和下一个&lt; right-square-bracket&gt;中是匹配的&lt; right-square-bracket&gt;结束转换规范;否则,第一个&lt; right-square-bracket&gt;是结束转换规范的那个。如果扫描列表中的“-”不是第一个字符,也不是第一个字符是“^”的第二个字符,也不是最后一个字符,则行为是实现定义的。< / p>

POSIX standard for scanf .C标准有类似的措辞,参见Adam Rosenfield的回答。)

因此,根据实现情况,您可以执行fscanf(fp, "%[A-Z]", str),但不能保证它可以在任何POSIX系统上运行。无论如何,[:upper:][:epru]相同。

答案 1 :(得分:2)

不,没有可移植的方式来做到这一点。某些实现允许您使用%[A-Z]之类的字符范围,但C标准无法保证这一点。 C99§7.19.6.2/ 12说明了[转换说明符(强调添加):

  

转换说明符包括format字符串中的所有后续字符,包括匹配的右括号(])。括号( scanlist )之间的字符组成了扫描集,除非左括号后面的字符是抑扬符(^),在这种情况下,扫描集包含所有不显示的字符在旋转和右支架之间的扫描列表中。如果转换说明符以[][^]开头,则右括号字符位于扫描列表中,下一个右括号字符是结束规范的匹配右括号;否则第一个右括号字符是结束规范的字符。 如果-字符在扫描列表中并且不是第一个字符,也不是第一个字符是^的第二个字符,也不是最后一个字符,则行为是实现定义的。

POSIX.1-2008 description具有几乎相同的措辞(在意外冲突的情况下甚至遵循ISO C标准),因此在使用POSIX系统时没有额外的保证。

答案 2 :(得分:0)

试试这个:

fscanf(fp, "%[A-Z]", str);