%[^n]在scanf()格式字符串中是什么意思
What does %[^ ] mean in a scanf() format string
我在这个网站上看到:fscanf(fin, "%[^n]", &p);
可以用于从我的输入文件(fin
)读取到字符类型指针(*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;
}
%[
表示法引入了一种称为"扫描集"的东西,它有点像正则表达式(但没有那么强大)。
在您的特定示例中,这意味着格式说明符指示scanf
继续扫描与除n
之外的任何字符匹配的字符(遇到不匹配的字符将终止扫描)。
来自C11标准:
转换说明符包括格式字符串,最多包含匹配的右括号(])。这个括号(扫描列表)之间的字符组成扫描集,除非左括号后的字符是扬抑符(^),在这种情况下,扫描集包含未出现在位于扬抑符和右括号之间的扫描列表。
即使将其与正则表达式进行比较,也会对其进行扩展:标准只是简单地说:"匹配一组预期字符中的非空字符序列"。
Jonathan Leffler发现的代码的真正问题是:
fscanf(fin, "%[^n]", &p);
^
删除&
,因为您要传递p,而不是"p的地址"。
%
引入了一个格式说明符,[
表示它是一个扫描集并打开它,扫描集中第一个位置的^
从"match all in"反转为"match allnotin",n
是换行符,]
关闭扫描集。
因此,它意味着:无限期地匹配许多不是n
的字符,并将它们放入参数所指向的char[]
中。
因此,该参数的类型必须为char*
&p
正是一个太多的地址,并且它所指向的缓冲区(new char[1001]
)太小了无数个数量级。
限制匹配的长度(通过在扫描集和%
之间放置1000)
或者,最好使用fgets
。
其他要点:
-
您的缓冲区应该是堆栈分配的,因为它足够小:
char buf[1001];
-
或者,至少使用一个智能指针,这样你就不会忘记
delete []
it:std::unique_ptr<char> p = new char[1001];
- 为什么要对其进行值初始化?这是多余的。使用
new char[1001]
而不是new char[1001]()
- 不要忘记检查
fscanf
的返回值,它应该是成功分配的次数 - C++(和C99)在CCD_ 25的末尾具有隐含的CCD_
- 您确实应该关闭所有打开的文件(
fopen
->fclose
)
- 是否可以从格式字符串中检索"width"
- 我应该如何从 stdin C++ 中读取可变长度的格式字符串?
- 从用户定义的类生成格式字符串?
- 如何连接格式字符串?
- 如何在C++中将"%Y%m%d"格式字符串转换为time_t变量?
- CPPCHECK C++成员函数上的格式字符串
- scanf() 语句中"%*[^n]"的格式字符串指示什么?分配抑制器 (*) 和否定扫描集 ([^) 如何协同工作?
- 自定义 {fmt} 格式化函数,具有编译时格式字符串检查功能
- '|' scanf 格式字符串是什么意思
- 如何使用 msgfmt 验证格式字符串中的位置表示法占位符
- sscanf_s:格式字符串"%d"需要类型为"int *"的参数,但可变参数 4 的类型为"WORD *"
- C4477: 'fprintf' :格式字符串 '%s' 需要类型为"char *"的参数,但可变参数 1 的类型为"int *"
- 如何使用OpenSSL API从其PEM格式字符串中读取RSA公钥
- C 格式字符串宏
- C++等效于 C 的格式字符串
- 如何使用 C++ 中的 rapidjson 库从 json 格式字符串中获取值
- _vsnprintf和_vsnprintf_s的格式字符串中的可用百分比字符
- 如何将格式字符串发送到iostream
- 跨平台格式字符串
- 使用 swprintf() 打印"0x0"的格式字符串应该是什么?