C 检查第一个参数是否为仅由十进制数字组成的有效数字
这是我试图用于“验证密钥”部分的代码,仅当参数是数字时才尝试返回成功。然而,当我运行我的程序时,一些数字被认为是错误的。我不明白为什么C 检查第一个参数是否为仅由十进制数字组成的有效数字,c,cs50,C,Cs50,这是我试图用于“验证密钥”部分的代码,仅当参数是数字时才尝试返回成功。然而,当我运行我的程序时,一些数字被认为是错误的。我不明白为什么 ~/pset2/caesar/ $ ./caesar 9 Usage: ./caesar key ~/pset2/caesar/ $ ./caesar 45 Success 45 #包括 #包括 #包括 #包括 #包括 int main(int argc,字符串argv[]){ int n=atoi(argv[1]); if(argc==2&&isdigit
~/pset2/caesar/ $ ./caesar 9
Usage: ./caesar key
~/pset2/caesar/ $ ./caesar 45
Success
45
#包括
#包括
#包括
#包括
#包括
int main(int argc,字符串argv[]){
int n=atoi(argv[1]);
if(argc==2&&isdigit(argv[1][n])){
printf(“成功\n%s\n”,argv[1]);
返回0;
}否则{
printf(“用法:./caesar key\n”);
返回1;
}
您的错误如下:
if (argc == 2 && isdigit(argv[1][n])) {
这一行没有意义,您正在检查第一个参数的第n个字符是否是数字,但是(1)您甚至不知道第一个参数是否有足够的字符(n
由atoi
返回,因此它可能是任意大的)和(2)您没有检查参数的所有数字
如果要检查给程序的第一个参数中的每个字符是否都是数字,可以通过两种方式进行检查:
isdigit()
进行检查:
#包括
#包括
int main(int argc,字符**argv){
char*c;
如果(argc!=2){
FPUT(“用法:./prog\n”,标准);
返回1;
}
对于(c=argv[1];*c!='\0';c++){
如果(!isdigit(*c)){
FPUT(“用法:./prog\n”,标准);
返回1;
}
}
printf(“成功!\n%s\n”,argv[1]);
返回0;
}
atoi
)的函数,因为它不会发出错误信号。使用strtol
还可以自动检查数字是否在可存储在long
中的值范围内(如果不是,则返回LONG\u MIN
或LONG\u MAX
,并适当设置errno
)
#包括
#包括
#包括
#包括
int main(int argc,字符**argv){
长数;
char*endp;
如果(argc!=2){
FPUT(“用法:./prog\n”,标准);
返回1;
}
errno=0;
num=strtol(argv[1],&endp,10);
if(endp==argv[1]| |*endp!='\0'| | errno==ERANGE){
FPUT(“用法:./prog\n”,标准);
返回1;
}
printf(“成功!\n%ld\n”,num);
返回0;
}
-
开头,则strtol
可以返回负值(例如-123
):如果不允许使用负数,您可能需要检查该值
当我运行我的程序时,一些数字被认为是错误的
对于像“123”
这样的输入参数,下面的代码尝试检查3个字符参数的第123个字符是否为数字。对argv[1]
外部“123”
的访问是未定义的行为(UB)-错误
要测试输入是否为所有数字:
argv[1]
之前,请检查预期的参数数
argv[1][]
int main(int argc, string argv[]) {
if (argc == 2) {
const char *digit = argv[1];
while (*digit >= '0' && *digit <= '9') {
digit++;
}
// If code reached the end of the string?
if (*digit == '\0') {
printf("Success\n%s\n", argv[1]);
return 0;
}
}
printf("Usage: ./caesar key\n");
return 1;
}
验证这些输入的正确方法是使用
strspn
并检查整个字符串。在几乎所有情况下strspn
都比任何手工编码的版本快,除非将验证和转换结合起来
下面是您的代码,其中验证函数正是这样做的:
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
int validate_arg(const char *s) {
size_t len;
len = strspn(s, "0123456789");
return len > 0 && !s[len];
}
int main(int argc, string argv[]) {
int n = atoi(argv[1]);
if (argc == 2 && validate_arg(argv[1])) {
printf("Success\n%s\n", argv[1]);
return 0;
} else {
printf("Usage: ./caesar key\n");
return 1;
}
}
#包括
#包括
#包括
#包括
#包括
int validate_arg(常量字符*s){
尺寸透镜;
len=标准参考编号(s,“0123456789”);
返回len>0&!s[len];
}
int main(int argc,字符串argv[]){
int n=atoi(argv[1]);
if(argc==2&&validate_arg(argv[1])){
printf(“成功\n%s\n”,argv[1]);
返回0;
}否则{
printf(“用法:./caesar key\n”);
返回1;
}
}
旁注:最好使用无符号类型,并使用
stroul
转换数字。请以可读的方式格式化代码。您需要检查每个argv[1][i]
,其中i
从0到strlen(argv[1])
。如果(argc==2…未正确检查是否有足够的参数。正确使用了strspn()
。是的,我没有纠正其他方面,只是验证。
int main(int argc, string argv[]) {
if (argc == 2) {
const char *digit = argv[1];
while (*digit >= '0' && *digit <= '9') {
digit++;
}
// If code reached the end of the string?
if (*digit == '\0') {
printf("Success\n%s\n", argv[1]);
return 0;
}
}
printf("Usage: ./caesar key\n");
return 1;
}
const unsigned char *digit = argv[1];
while (isdigit(*digit)) {
digit++;
}
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
int validate_arg(const char *s) {
size_t len;
len = strspn(s, "0123456789");
return len > 0 && !s[len];
}
int main(int argc, string argv[]) {
int n = atoi(argv[1]);
if (argc == 2 && validate_arg(argv[1])) {
printf("Success\n%s\n", argv[1]);
return 0;
} else {
printf("Usage: ./caesar key\n");
return 1;
}
}