验证输入 cmdline 输入 argv[] 包含所有整数

发布于 2024-10-17 06:06:27 字数 187 浏览 0 评论 0原文

所以我有一个处理数字操作的作业,其中还包括错误检查。我在错误检查方面遇到问题。用户通过命令行并提供 8 个以空格分隔的数字来使用该应用程序。我在验证提供的数据实际上是整数时遇到问题。

建议我使用 strtol() 方法,但是我知道如果整数无效,它会返回 0,但我需要返回错误消息而不是 0,因为 0 是有效的。我可以使用另一种方法来验证输入吗?

So I have an assignment dealing with number manipulation that also includes error checking. I'm having issues with the error checking side. A user uses the application by via commandline and giving 8 numbers that are space separated. I am having a problem validating that the data provided are actually integers.

I was suggested to use the method strtol() however I know that if the integer is invalid, it returns a 0, but I need to return an error message instead of a 0 because 0 is valid. Is there another method I can use to validate input?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

温柔嚣张 2024-10-24 06:06:27

strtol 不仅有其返回值来指示转换中的错误,它还有第二个参数(我的手册页中的 endptr);如果您向其传递一个指向 char * 的指针,它将存储无法转换的第一个字符的位置,或者如果无法转换任何内容,则将其保留。因此,您会遇到以下情况:

char * endptr=NULL;
int out=strtol(yourstring, &endptr, 10);
if(endptr==NULL)
{
    /* the whole string is garbage - no numbers extracted */
}
else if(*endptr==0)
{
    /* the whole string was a number - yay! */
}
else
{
    /* strtol extracted a number from the string, but stopped at some invalid character
       that you can check by looking at the value of endptr */
}

此外,您还可以检查 strtol 设置 errno 的值,以防出现问题;如果无法提取任何内容,则使用EINVAL,其他值可以在strtol的联机帮助页上看到。

您还可以使用 sscanf 并检查其返回值,以快速查看字符串是否可以转换为 int(或您在格式字符串中设置的任何内容)。

strtol do not have only its return value to signal an error in the conversion, it has also its second parameter (endptr in my manpage); if you pass to it a pointer to a char *, it will store there the position of the first character that it couldn't convert, or will leave it alone if nothing could be converted. Thus, you have the following cases:

char * endptr=NULL;
int out=strtol(yourstring, &endptr, 10);
if(endptr==NULL)
{
    /* the whole string is garbage - no numbers extracted */
}
else if(*endptr==0)
{
    /* the whole string was a number - yay! */
}
else
{
    /* strtol extracted a number from the string, but stopped at some invalid character
       that you can check by looking at the value of endptr */
}

Moreover, you can also check the value to which strtol sets errno in case of problems; EINVAL is used if nothing could be extracted, the other values can be seen on the manpage of strtol.

You can also use sscanf and check its return value to quickly see if the string could or could not be converted to int (or to whatever you set in the format string).

初心 2024-10-24 06:06:27

如果strtol()遇到错误,它会将errno设置为EINVAL。从 手册页

返回值

strtol() 函数返回转换结果,除非该值下溢或上溢。 ...在这两种情况下,errno 均设置为 ERANGE。 ...

错误

EINVAL...给定的基数包含不受支持的值。 ...

如果没有执行转换(没有看到数字,并返回 0)。

If strtol() encounters an error, it will set errno to EINVAL. From the man page:

Return Value

The strtol() function returns the result of the conversion, unless the value would underflow or overflow. ...In both cases, errno is set to ERANGE. ...

Errors

EINVAL...The given base contains an unsupported value. ...

The implementation may also set errno to EINVAL in case no conversion was performed (no digits seen, and 0 returned).

或十年 2024-10-24 06:06:27

命令行参数是字符串,为什么不使用 <代码>isdigit(3)

The command line arguments are strings, why not use isdigit(3)?

绝不服输 2024-10-24 06:06:27

要正确使用 strtol,您必须在调用它之前重置 errno。如果您编写想要在其他项目中重用的代码,则该代码不应产生意外的副作用。因此有两种变体:一种简单的变体可能适合您的情况,另一种复杂的变体在可重用代码库中可以接受。

#include <errno.h>
#include <stdbool.h>
#include <stdlib.h>

/* the simple variant, with the side-effect of changing errno */
static bool is_long_1(const char *s)
{
  char *end;

  errno = 0;
  strtol(s, &end, 10);
  return errno == 0 && *end == '\0';
}

/* the complex variant, without side-effects */
static bool is_long_2(const char *s)
{
  char *end;
  int saved_errno = errno;
  errno = 0;

  strtol(s, &end, 10);
  bool succeeded = errno == 0 && *end == '\0';
  errno = saved_errno;
  return succeeded;
}

使用这些函数之一来检查你的参数应该很容易,所以我把这部分留给你去发现。

To use strtol properly, you have to reset errno before calling it. And if you write code that you want to reuse in other projects, that code should have no unintended side-effects. So there are two variants: a simple one that is probably good enough in your case, and a complex one that would be acceptable in a library of reusable code.

#include <errno.h>
#include <stdbool.h>
#include <stdlib.h>

/* the simple variant, with the side-effect of changing errno */
static bool is_long_1(const char *s)
{
  char *end;

  errno = 0;
  strtol(s, &end, 10);
  return errno == 0 && *end == '\0';
}

/* the complex variant, without side-effects */
static bool is_long_2(const char *s)
{
  char *end;
  int saved_errno = errno;
  errno = 0;

  strtol(s, &end, 10);
  bool succeeded = errno == 0 && *end == '\0';
  errno = saved_errno;
  return succeeded;
}

Using one of these functions for checking your arguments should be quite easy, so I leave that part to you to find out.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文