#include <stdio.h>
#include <stdlib.h>
int
main(int argc,char **argv)
{
char *cp;
long lval;
int val;
// skip over program name
--argc;
++argv;
if (argc < 1) {
fprintf(stderr,"main: no argument specified\n");
exit(1);
}
cp = *argv;
if (*cp == 0) {
fprintf(stderr,"main: argument an empty string\n");
exit(1);
}
lval = strtol(cp,&cp,10);
if (*cp != 0) {
fprintf(stderr,"main: argument '%s' is not an integer -- '%s'\n",
*argv,cp);
exit(1);
}
val = (int) lval;
// NOTE: just going for extra credit here ;-)
// ensure number fits in a int (since strtol returns long and that's 64
// bits on a 64 bit machine)
#if 1
if (val != lval) {
fprintf(stderr,"main: argument '%s' (with value %ld) is too large to fit into an integer -- truncated to %d\n",
*argv,lval,val);
exit(1);
}
#endif
printf("val=%d\n",val);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
int
main(int argc,char **argv)
{
char *cp;
long lval;
int val;
// skip over program name
--argc;
++argv;
if (argc < 1) {
fprintf(stderr,"main: no argument specified\n");
exit(1);
}
cp = *argv;
if (*cp == 0) {
fprintf(stderr,"main: argument an empty string\n");
exit(1);
}
errno = 0;
lval = strtol(cp,&cp,10);
if (*cp != 0) {
fprintf(stderr,"main: argument '%s' is not an integer -- '%s'\n",
*argv,cp);
exit(1);
}
// on a 32 bit machine, entering 2147483648 will produce a non-zero errno
if (errno) {
fprintf(stderr,"main: argument '%s' parse error -- '%s'\n",
*argv,strerror(errno));
exit(1);
}
// on a 64 bit machine, entering 2147483648 will not produce an error, so
// we should check the range ourselves
if ((lval < INT_MIN) || (lval > INT_MAX)) {
fprintf(stderr,"main: argument '%s' range error -- %ld outside of range (%ld to %ld)\n",
*argv,lval,(long) INT_MIN,(long) INT_MAX);
exit(1);
}
val = (int) lval;
// NOTE: just going for extra credit here ;-)
// ensure number fits in a int (since strtol returns long and that's 64
// bits on a 64 bit machine)
// FIXME -- with above tests this can never be true (i.e. fault), so
// I've nop'ed it -- left in to show prior/original test
#if 0
if (val != lval) {
fprintf(stderr,"main: argument '%s' (with value %ld) is too large to fit into an integer -- truncated to %d\n",
*argv,lval,val);
exit(1);
}
#endif
printf("val=%d\n",val);
return 0;
}
for (int a = 1; a < argc; a++) {
int_validation(argv[a]);
}
1.尝试使用strtol()进行转换
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
void int_validation(const char *s) {
// If leading space not OK
// isspace() only valid in unsigned char range and EOF.
if (isspace(*(unsigned char *)s)) {
puts("Fail - leading spaces");
return;
}
// Convert
int base = 0; // Use 10 for base 10 only input
char *endptr;
errno = 0;
long val = strtol(s, &endptr, base);
if (s == endptr) { // When endptr is same as s, no conversion happened.
puts("Fail - no conversion");
return;
}
// detect overflow
if (errno == ERANGE || val < INT_MIN || val > INT_MAX) {
errno = ERANGE;
puts("Fail - overflow");
return;
}
// If trailing space OK, seek pass them
while (isspace(*(unsigned char *)endptr)) {
endptr++;
}
// If trailing non-numeric text bad
if (*endptr) {
puts("Fail - overflow");
return;
}
printf("Success %d\n", (int) val);
return;
}
#include <stdio.h>
#include <stdbool.h>
#include <ctype.h>
#include <stdlib.h>
bool is_all_digits(char *s)
{
bool b = true;
for( ; *s ; ++s)
if(!isdigit(*s))
{
b = false;
break;
}
return b;
}
int main(int argc, char *argv[])
{
for(int i = 0 ; i < argc ; ++i)
{
if(is_all_digits(argv[i]))
printf("argv[%d] is an integer = %d\n", i, atoi(argv[i]));
else
printf("argv[%d] is not an integer \"%s\"\n", i, argv[i]);
}
return 0;
}
使用命令行参数运行时
123 "Not a number" 456.789 "Not another number" 10
产生以下输出:
argv[0] is not an integer "./a.out"
argv[1] is an integer = 123
argv[2] is not an integer "Not a number"
argv[3] is not an integer "456.789"
argv[4] is not an integer "Not another number"
argv[5] is an integer = 10
#define TRUE 1
#define FALSE 0
int is_integer( char *s )
{
int i = 0 ;
int is_digit;
int is_sign;
while ( s[i] != '\0' )
{
// this test makes the assumption that the code points for
// decimal digits are contiguous. True for ASCII/UNICODE and EBCDIC.
// If you're using some other bizarro encoding, you're out of luck.
is_digit = s[i] >= '0' && s[i] <= '9' ? TRUE : FALSE ;
is_sign = i == 0 && s[i] == '-' ? TRUE : FALSE ;
if ( !is_digit && !is_sign )
{
return FALSE;
}
++i;
}
return TRUE;
}
int main( int argc, char *argv[] )
{
int i = 0 ;
int cc = 0 ; // assume success;
for ( i = 0 ; i < argc ; ++i )
{
if ( !is_integer(argv[i]) )
{
cc = 1;
}
}
return cc; // exit code 0 is success; non-zero exit code is failure.
}
6条答案
按热度按时间5cg8jx4n1#
下面是一种方法,使用
strtol
并检查字符串的结尾:次要:代码未检测strtol()的转换溢出代码错误地假定long范围大于int。如果范围相同,则
if (val != lval)
始终为true。建议查看errno, INT_MAX,INT_MIN
kninwzqo2#
C语言中的命令行参数验证
我需要检查argv是否是整型
1.首先通过检查
argc
来测试argv[]
是否包含字符串。1.尝试使用
strtol()
进行转换根据需要调整返回类型和消息。
通常,
"1e5"
或"123.0"
等输入虽然在数学上是整数,但不被视为有效的int
输入。jtoj6r0c3#
您可以尝试使用
strtol()
转换参数,如果值不可解析或解析后的值,它将返回0
。您还可以使用第二个参数对输入进行更详细的验证,您可以区分错误的输入或
0
输入,因为在这两种情况下返回的值都是0
。acruukt94#
使用
isdigit
测试参数的字符是否为“digit-ness”,然后根据结果转换(或不转换)参数。例如:使用命令行参数运行时
产生以下输出:
正如其他人所指出的,
is_all_digits
并不保证表示整数的字符串可以使用atoi
或任何其他例程进行解析,但您可以根据自己的需要随意修改它。:-)wlsrxk515#
作为
strtol()
(即 * 规范答案 *)的替代方法,您可以使用isdigit()
function执行 * 手工 * 验证,同时检查 * 前导符号字符 *(+
和-
):这个实现依赖于输入字符串以空结尾的事实,但是因为每个
argv[N]
都是以空结尾的字符串,所以我们可以很好地处理。用法:
注意(1):这个验证器不检查超过
int
范围(从INT_MIN
到INT_MAX
)的输入值,这是一个在很多情况下可以接受的限制。注(2):此函数不像
strto*
那样进行前导空格的修剪,如果需要此功能,可以在for-loop
的顶部添加这样的检查:通过这种方式,空格是可以容忍的,但只能在
flag
设置为false
之前,即遇到第一个非空格字符时。hfyxw5xn6#
试试这个。我会让你按自己喜欢的方式对错误消息进行排序: