scanf正则表达式 - C.

pas*_*has 5 c regex scanf

我需要读取一个字符串,直到写入以下序列:\nx \n:

(.....)\n
x\n
Run Code Online (Sandbox Code Playgroud)

\n是新行字符,(.....)可以是任何可能包含其他\n字符的字符.

据我所知,scanf允许正则表达式,但我不能让它读取字符串直到这个模式.你能帮我解决scanf格式字符串吗?


我在尝试这样的事情:

char input[50000];
scanf(" %[^(\nx\n)]", input);
Run Code Online (Sandbox Code Playgroud)

但它不起作用.

das*_*ght 15

scanf 据我所知,允许正则表达式

不幸的是,它不允许使用正则表达式:语法错误地接近,但是在实现中没有任何东西甚至与正则表达式类似scanf.所有这些都支持正则表达式的字符类,因此%[<something>]被隐式处理为[<something>]*.这就是为什么你的调用scanf转换为读取由字符以外的字符组成的字符串的原因'(', ')', 'x', and '\n'.

要解决您手头的问题,您可以设置一个循环,逐个字符地读取输入字符.每次你得到一个'\n',检查一下

  • 到目前为止,您输入的输入中至少有三个字符,
  • 紧接着之前的角色'\n''x',和
  • 之前的角色'x'是另一个'\n'

如果以上都是真的,那么您已达到预期输入序列的末尾; 否则,你的循环应该继续.


zwo*_*wol 13

scanf 支持正则表达式.它对字符类的支持有限,但这根本不是一回事.

永远不要使用scanf,, fscanfsscanf因为:

  1. 数字溢出会触发未定义的行为.允许C运行时使程序崩溃只是因为有人输入了太多数字.
  2. 某些格式说明符(特别是%s)以不完全相同的方式gets不安全,即它们会愉快地写入提供缓冲区的末尾并使程序崩溃.
  3. 它们使得处理格式错误的输入非常困难.

对于这种情况,您不需要正则表达式; 一次读取一行,getline当读取的行只是"x"时停止.但是,标准(ISO不C,但是POSIX)正则表达式库函数调用regcompregexec.

  • 请注意,scanf的大多数(全部?)实际实现(包括在GNU系统上)不会使程序崩溃或在整数溢出时做任何令人讨厌的事情.讨论[这里](https://groups.google.com/forum/#!topic/comp.std.c/P-VPAMpZu9c)表明该标准可以重新措辞,以要求理智的行为,可能没有实施可能会有改变.(特别是[Keith Thompson的帖子](https://groups.google.com/d/msg/comp.std.c/P-VPAMpZu9c/6kELb3kuBPMJ)).但是,按照标准措辞,伪造输入上的scanf仅在"好"C实现上是安全的,并且不可移植. (3认同)
  • 注意:问题 #2 可以通过使用长度修饰符来避免。 (2认同)
  • @CoolGuy 我一般认为,如果你必须采取额外的、可选的步骤来*避免*搬起石头砸自己的脚,那么这是一个设计糟糕的 API。 (2认同)