scanf错误处理C

Jon*_*ono 3 c error-handling

说如果我想输入

[Name] [Name]
Run Code Online (Sandbox Code Playgroud)

我将如何检测

[Name] [Name] [Name] 
Run Code Online (Sandbox Code Playgroud)

并返回错误?

这是我到目前为止的一切

char in[20];
char out[20];
scanf(" %s %s", out, in);
Run Code Online (Sandbox Code Playgroud)

Con*_*ius 5

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
}
Run Code Online (Sandbox Code Playgroud)

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

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


Chr*_*utz 5

这是家庭作业,因此可能需要您在某些(任意)限制下工作。但是,短语“ scanf错误处理”在C编程语言中有点矛盾。

最好做到这一点的办法是在一条线上/其他合适的块读取和使用C字符串函数解析它。您可以单行执行此操作,scanf但是有很多缺点:

  1. 您可以防止缓冲区溢出,但是如果缓冲区不够大,您将无法恢复。
  2. 您可以为字符串指定特定的字符范围,但是看起来有点不规则,并且标准中没有强制规定"%["格式的行为scanf
  3. 您可以检查第三个名称,但是代码看起来不直观-它看起来不像只需要两个名称,而是像您想要三个名称。scanf还使您几乎无法控制如何处理空白。

编辑:我最初从您的问题中想到,名称包含在方括号(la "[Bruce] [Wayne]")中,但现在看来,这仅仅是您用来表示占位符的约定。

无论如何,尽管我非常不喜欢scanf它,但它有其用途。(对我而言)最大的杀手是无法区分行尾和简单的空格分隔。要解决此问题,您可以调用fgets将数据读入缓冲区,然后调用sscanf该缓冲区。这既给您带来了(a)更安全的读取(scanf使其他更直接的函数无法读取缓冲区的功能)又使b)scanf格式的好处。

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

" %s %s %s"
Run Code Online (Sandbox Code Playgroud)

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

如果您错过了之前我偷偷找的那fgets一页,这里是指向手册页的链接。如果您决定放弃sscanf,这里还有一些其他功能需要研究:(strchrstrspn,或strcspn)查找名称的长度,strcpy或者memcpy(或(但不要那样strncpy,不是您想的那样))将数据复制到缓冲区中。