scanf 错误处理 C
假设如果我想要一个输入,
[Name] [Name]
我将如何检测
[Name] [Name] [Name]
并返回错误?
这是我到目前为止所拥有的,
char in[20];
char out[20];
scanf(" %s %s", out, in);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
scanf
返回有效转换的参数的数量。因此,在第一种情况下,返回值将为 2,在后一种情况下为 3。要检查参数的正确数量,这可能会有所帮助:
编辑:现在它应该可以工作,请参阅下面的评论。
当然,正如其他海报所述: scanf 不被认为是一个非常安全的函数,因为可能会发生缓冲区溢出,您应该避免使用它。最好使用 fgets() 读取缓冲区的输入并尝试解析所需的参数。
scanf
returns the number of validly converted arguments. So in your first case, the return value would be 2, in the latter case 3.To check the right amount of parameters, this might help:
EDIT: now it should be working, see comments below.
Of course, as stated by other posters: scanf is not considered a quite safe function since buffer overflows can occur, and you should avoid using it. It is better to read the inputs to a buffer with
fgets()
and the try to parse the arguments you want.这是家庭作业,因此您可能需要在某些(任意)限制下工作。然而,短语“
scanf
错误处理”在 C 编程语言中有些矛盾。执行此操作的最佳方法是读取一行/其他合适的块并使用 C 字符串函数对其进行解析。您可以在一行
scanf
中完成此操作,但有很多缺点:scanf
的"%["
格式的行为在标准。scanf
还让您无法控制如何处理空白。编辑:我最初从你的问题中认为这些名称包含在括号中(a la
“[Bruce] [Wayne]”
),但现在看来这只是你表示占位符的惯例。不管怎样,尽管我非常不喜欢
scanf
,但它也有它的用处。 (对我来说)最大的杀手是无法区分行尾和简单的空间分隔。要解决此问题,您可以调用fgets
将数据读入缓冲区,然后在缓冲区上调用sscanf
。这为您提供了 a) 更安全的读取(scanf
与其他更简单的函数从缓冲区读取的能力相混淆)和 b)scanf
格式的好处。如果您必须使用
scanf
,您的格式基本上是这样的:第三个是不可取的。正如 @Constantinius 的答案所示,您需要将数据读入三个缓冲区,并检查第三个缓冲区是否通过。但是,如果您正在读取此数据的多个连续行,则下一行的第一个条目将满足第三个槽,从而错误地给出错误。我强烈建议使用
fgets
和sscanf
或放弃sscanf
在这种情况下进行更精确的手动解析。以下是
fgets
手册页的链接 如果你错过了我之前偷偷溜进来的那个。如果您决定放弃 sscanf,请研究以下一些其他函数:strchr
(或strspn
,或strcspn
) 来查找名称的长度,strcpy
或memcpy< /code>
(但请不要使用
strncpy
,它不是您想象的那样)将数据复制到缓冲区中。This is homework, so you might be required to work under certain (arbitrary) restrictions. However, the phrase "
scanf
error handling" is something of an oxymoron in the C programming language.The best way to do this is to read in a line/other suitable chunk and parse it with C string functions. You can do it in one line of
scanf
but there are many drawbacks:"%["
format ofscanf
isn't mandated in the standard.scanf
also gives you very little control over how you handle whitespace.EDIT: I initially thought from your question that the names were contained in brackets (a la
"[Bruce] [Wayne]"
) but it now appears that was merely your convention for denoting a placeholder.Anyway, despite my intense dislike of
scanf
, it has its uses. The biggest killer (for me) is the inability to distinguish between line endings and simple space separation. To fix that, you can callfgets
to read the data into a buffer, then callsscanf
on the buffer. This gives you both a) safer reading (scanf
messes with the ability of other more straightforward functions to read from a buffer) and b) the benefits ofscanf
formats.If you have to use
scanf
, your format basically be this:With the third being undesirable. As @Constantinius's answer shows, you'd need to read data into three buffers, and check whether or not the third passed. However, if you're reading multiple consecutive lines of this data, then the first entry of the next line would satisfy the third slot, falsely giving you an error. I highly recommend using
fgets
andsscanf
or ditching thesscanf
for more precise manual parsing in this case.Here's a link to the
fgets
man page if you missed the one I snuck in earlier. If you decide to ditchsscanf
, here are some other functions to look into:strchr
(orstrspn
, orstrcspn
) to find how long the name is,strcpy
ormemcpy
(but please notstrncpy
, it's not what you think it is) to copy data into the buffers.