scanferror handlingC.
说如果我想要输入
[Name] [Name]
我怎么会发现
[Name] [Name] [Name]
并返回错误?
这是我到目前为止所拥有的,
char in[20]; char out[20]; scanf(" %s %s", out, in);
这是家庭作业,因此您可能需要在某些(任意)限制下工作。 然而,短语“ scanf
error handling”在C编程语言中是矛盾的。
执行此操作的最佳方法是读取一行/其他合适的块并使用C字符串函数对其进行解析。 你可以在一行scanf
完成它,但有许多缺点:
- 您可以防止缓冲区溢出,但如果缓冲区不够大,则无法恢复。
- 您可以为字符串指定特定的字符范围,但它开始看起来有点regexy,并且标准中不强制执行
scanf
的"%["
格式的行为。 - 您可以检查第三个名称,但代码看起来不直观 – 看起来您只想要两个名称,看起来您想要三个名称。
scanf
还可以很好地控制你如何处理空格。
编辑:我最初从你的问题中想到这些名字都包含在括号中(la "[Bruce] [Wayne]"
)但现在看来这只是表示占位符的惯例。
无论如何,尽管我非常不喜欢scanf
,但它有其用途。 最大的杀手(对我而言)是无法区分线路末端和简单的空间分离。 要解决此问题,您可以调用fgets
将数据读入缓冲区, 然后在缓冲区上调用sscanf
。 这为您提供了a)更安全的读取( scanf
混乱,具有从缓冲区读取其他更直接的function的能力)和b) scanf
格式的好处。
如果你必须使用scanf
,你的格式基本上是这样的:
" %s %s %s"
第三个是不受欢迎的。 正如@Constantinius的回答所示,您需要将数据读入三个缓冲区,并检查第三个缓冲区是否通过。 但是,如果您正在读取此数据的多个连续行,则下一行的第一个条目将满足第三个插槽,错误地给您一个错误。 在这种情况下,我强烈建议使用fgets
和sscanf
或抛弃sscanf
以进行更精确的手动解析。
如果你错过了我之前fgets
那个,那么这里是fgets
手册页的链接。 如果你决定strchr
sscanf
,这里有一些其他的function可以查看: strchr
(或strspn
,或strcspn
)来查找名称是多长, strcpy
或memcpy
(但请不要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()
读取缓冲区的输入,并尝试解析所需的参数。