scanferror handlingC.

说如果我想要输入

[Name] [Name] 

我怎么会发现

 [Name] [Name] [Name] 

并返回错误?

这是我到目前为止所拥有的,

 char in[20]; char out[20]; scanf(" %s %s", out, in); 

这是家庭作业,因此您可能需要在某些(任意)限制下工作。 然而,短语“ scanferror handling”在C编程语言中是矛盾的。

执行此操作的最佳方法是读取一行/其他合适的块并使用C字符串函数对其进行解析。 你可以在一行scanf完成它,但有许多缺点:

  1. 您可以防止缓冲区溢出,但如果缓冲区不够大,则无法恢复。
  2. 您可以为字符串指定特定的字符范围,但它开始看起来有点regexy,并且标准中不强制执行scanf"%["格式的行为。
  3. 您可以检查第三个名称,但代码看起来不直观 – 看起来您只想要两个名称,看起来您想要三个名称。 scanf还可以很好地控制你如何处理空格。

编辑:我最初从你的问题中想到这些名字都包含在括号中(la "[Bruce] [Wayne]" )但现在看来这只是表示占位符的惯例。

无论如何,尽管我非常不喜欢scanf ,但它有其用途。 最大的杀手(对我而言)是无法区分线路末端和简单的空间分离。 要解决此问题,您可以调用fgets将数据读入缓冲区, 然后在缓冲区上调用sscanf 。 这为您提供了a)更安全的读取( scanf混乱,具有从缓冲区读取其他更直接的function的能力)和b) scanf格式的好处。

如果你必须使用scanf ,你的格式基本上是这样的:

 " %s %s %s" 

第三个是不受欢迎的。 正如@Constantinius的回答所示,您需要将数据读入三个缓冲区,并检查第三个缓冲区是否通过。 但是,如果您正在读取此数据的多个连续行,则下一行的第一个条目将满足第三个插槽,错误地给您一个错误。 在这种情况下,我强烈建议使用fgetssscanf或抛弃sscanf以进行更精确的手动解析。

如果你错过了我之前fgets那个,那么这里是fgets手册页的链接。 如果你决定strchr sscanf ,这里有一些其他的function可以查看: strchr (或strspn ,或strcspn )来查找名称是多长, strcpymemcpy (但请不要strncpy ,这不是你认为的那样)到将数据复制到缓冲区中。

scanf返回有效转换的参数的数量。 所以在你的第一种情况下,返回值将是2,在后一种情况下为3。

要检查正确数量的参数,这可能会有所帮助:

 char in[20]; char out[20]; char error[20]; int check; check = scanf(" %s %s %s", out, in, error); if(check != 2) { // TODO: error handling } 

编辑:现在它应该工作,请参阅下面的评论。

当然,正如其他海报所述:scanf不被认为是一个非常安全的function,因为可能会发生缓冲区溢出,你应该避免使用它。 最好使用fgets()读取缓冲区的输入,并尝试解析所需的参数。