【问题标题】:Reading input and printing specific output读取输入并打印特定输出
【发布时间】:2020-02-06 14:57:36
【问题描述】:

我希望用 C 编写一个程序,它读取输入并只打印某些输出(特别是它省略了 cmets)。

澄清:我希望它的行为与 C 处理器完全一样。我相信 C 处理器会用空格替换 cmets,所以一旦我检测到注释的结尾,我就可以用空格替换它。

这意味着这个程序应该正确处理三元组、转义引号和其他可能影响 cmets 的事情。

该函数忽略其输入中的任何注释字符。例如,除了字符串中的输入,它会忽略所有 C 注释形式的输入(例如,/**/ 之间的输入以及// 和换行符 (\n) 之间的输入)。

请注意,在第二种情况下,会打印换行符,而在第一种情况下,/**/ 都不会打印。

然而,在一个字符串中(例如"hello //world"),程序将打印注释说明符之后的任何内容(在这种情况下,它会打印"hello //world",即使“world”前面有一个单行C-注释说明符)。

到目前为止,我已经尝试考虑过几种情况。我考虑过定义两个变量sngl_linemulti_line 来确定输入何时在a // 和a \n 之间(即sngl_line 为真)或输入何时在/**/ 之间(即multi_line 是真的)。 我编写了一个忽略字符串之外的 cmets 的程序,但我发现处理三元组特别成问题。也许我应该稍后再处理它们?

我还希望我的程序产生错误(例如,如果有非终止双引号或注释,它会打印适当的错误消息)。 注意:我已经成功编写了一个程序,它可以按预期忽略 cmets(除非字符串中存在三元组)。所以我不希望看到任何有效的 C 代码;只需一些关于如何产生正确错误的一般提示就足够了。

【问题讨论】:

  • 有很多关于在 C 代码中删除 cmets 的问题的答案。请注意,'//' 也不会开始评论。注意“单行”注释行末尾的反冲换行符。注意/**/// 中间的反斜杠换行符。另请注意,编译器会将注释替换为空白(空格)。
  • 为什么要重新发明轮子?你检查过他的 C 预处理器吗?
  • @AdrianCornish 有时最好的学习方法是重新发明一个已有的轮子。如果 OP 以前没有使用过状态机,这将是学习它们的一个很好的练习。
  • @TripeHound 公平点,但新编码人员也会浪费数百万工时来完成已完成的工作。
  • @AdrianCornish 新程序员如果只是加入其他人的库,就永远不会成为优秀老程序员。 某人必须足够优秀才能编写新库!

标签: c input output


【解决方案1】:

使用state machine

处理输入,就好像您处于以下状态之一:

  1. 正常
  2. 在“”内
  3. 里面''
  4. 在 /* */ 注释内
  5. 在 // 行尾注释内

每个状态都有一些如何转换到另一个状态的规则。

例如从 // 注释状态,一直停留到行尾,然后进入正常状态。
正常开始,如果下一个字符是//,则跳转到 // 评论状态。
正常开始,如果下一个字符是/*,则跳转到/*评论状态。

这确实是一项最有价值的编程任务,所以我不再列出。


看起来 OP 的数据没有行使 '' 状态。

【讨论】:

  • 您还需要跟踪刚刚看到的反斜杠 ("\"),它本身可能不一定是一个状态(或一组状态),但可以修改下一个字符如何转换为一个新的状态与否。此外,还有一个状态 3a。那就是“看到/”(根据下一个字符,可能会转换为3.、4.或1.
  • @TripeHound 我提出的 states 长度不定。一般来说,反斜杠转义、/**/// 是短有限(讨厌的十六进制除外),可以作为标记分析或不分析到下一个状态。真正的一个可以创建许多次要状态 - 我只是将那些小的状态作为令牌解码处理。
  • @TripeHound 你从哪里知道反斜杠在这里是一个特殊字符?
  • @hyde 示例:在"" 状态下,反斜杠 " 不会结束该状态。即使 OP 的数据集不使用它——因此对于该数据可能可以忽略——但通常不会。
  • @hyde 澄清一下,我希望我的程序能够以 C 预处理器忽略 cmets 的方式工作。我想处理所有特殊情况(例如,转义引号)。
猜你喜欢
  • 1970-01-01
  • 2011-09-14
  • 2019-01-31
  • 1970-01-01
  • 1970-01-01
  • 2014-02-16
  • 1970-01-01
  • 1970-01-01
  • 2019-07-17
相关资源
最近更新 更多