我在这个网站上看到:fscanf(fin, "%[^\n]", &p);
可用于从我的输入文件(fin
)读取到该char类型指针(*p
)所有字符,直到第一个输入命中。在某些输入它可以正常工作,但在其他输入它没有。
这是我应该处理的输入而我不能:
(((zahar 100 ou 3) 5 unt 100 nuca 200) 4 (lapte 200 cacao 50 zahar 100)3)20
这是我的全部代码:
#include <string.h>
#include <stdio.h>
FILE *fin, *fout;
int main()
{
fin = fopen("reteta.in", "r");
fout = fopen("reteta.out", "w");
char *p;
p = new char[1001]();
fscanf(fin, "%[^\n]", &p);
fprintf(fout, "%s", &p);
return 0;
}
答案 0 :(得分:4)
%[
符号引入了一种称为“scanset”的东西,它有点像正则表达式(但不是那么强大)。
在您的具体示例中,它表示格式说明符指示scanf
保持扫描与\n
之外的任何内容匹配的字符(遇到不匹配的字符将终止扫描)。
来自C11标准:
转换说明符包括中的所有后续字符 格式字符串,包括匹配的右括号(])。该 括号之间的字符(扫描列表)组成扫描集, 除非左括号后的字符是旋音(^), in 在哪种情况下,scanset包含所有未出现的字符 旋转和右支架之间的扫描列表。
即使将它与正则表达式进行比较也会拉伸它:标准简单地说:“匹配来自一组预期字符的非空字符序列”。
Jonathan Leffler发现你的代码存在的真正问题是:
fscanf(fin, "%[^\n]", &p);
^
删除&
,因为您要传递p,而不是“p的地址”。
答案 1 :(得分:2)
%
introduces a format-specifier,[
表示它是扫描设置并打开它,^
在扫描设置的第一个位置反转来自&#34;匹配全部&# 34;要&#34;匹配&#34;中的所有不,\n
是换行符,]
会关闭扫描集。
因此,它意味着:无限期地匹配许多不是\n
的字符,并将它们放入参数所指向的char[]
中。
因此,该论点必须具有char*
类型
&p
只是一个地址 - 太多,它所指向的缓冲区(new char[1001]
)的数量级太小。
限制匹配的长度(通过在扫描集和%
之间放置1000)
或者,更好的是,使用fgets
。
其他要点: