【问题标题】:How do I Validate a Key in ARGV?如何验证 ARGV 中的密钥?
【发布时间】:2019-12-11 00:00:19
【问题描述】:

我被困住了。这几天一直在努力。我需要验证输入到argv[1] 的每个字符都是一个数字,但我尝试了isdigitisalphacharatoi 转换但没有任何成功。我在编码方面还是新手。我很沮丧并删除了所有内容以重新开始,但这就是我现在所处的位置。

#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>

int main(int argc, string argv[])
{
    if (argc == 2)        
    {
        for (int k = 0; k <strlen(argv[1]); k++)
        {
            printf("Success!\n");
            printf("%s\n", argv[1]);
        }    
    }     
    else                  
    {
        printf("Usage: ./caesar key\n");
    }
}

这是我以前的位置。每次尝试运行此程序时,我都会收到一个清理错误:

#include <cs50.h>
#include <stdio.h>
#include <string.h>
include <ctype.h>
#include <stdlib.h>

int main(int argc, string argv[])
{
    if (isdigit(argv[1]))
    {
        if(atoi(argv[1])) 
        {
            if (argc == 2)
            {         
                for (int x = 0; x < strlen(argv[1]); x++)
                {
                    printf("Success!\n");
                    printf("%s", argv[1]);
                }
            }        
        }
    }
    else
    {
        printf("Usage: /caesar key\n");
    }
}

任何帮助将不胜感激!

【问题讨论】:

  • isdigit 仅适用于单个 char。您可以使用 isdigit 遍历整个字符串。
  • 想想你做事的顺序......在第二个例子中,你检查是否有参数(即argv[1]是有效的)你使用那个参数之后。
  • if (isdigit(argv[1])) 正在检查地址是否为char 数字。
  • 当你写“每个输入到 argv[1] 的字符都是一个数字”时,你的意思是 argv[1] 中的每个字符都必须是一个数字吗?
  • 您如何编写一个函数int all_digits(char *s); 来查看字符串中的每个字符,如果所有字符都是数字则返回 1(又名真),如果不是数字则返回 0(又名假)?

标签: c cs50 argv atoi argc


【解决方案1】:

一个快速而肮脏的例子on onlinegdb

没有测试很多...

#include <stdio.h>
#include <string.h>

int main(int argc, char * argv[])
{
    if (argc == 2)        
    {
        int n = strlen(argv[1]);
        for (int k = 0; k < n; k++)
        {
            if ( isdigit(argv[1][k]) )
            {
                printf("%c is a digit\n", argv[1][k]);
            }
            else
            {
                printf("%c is not a digit\n", argv[1][k]);
            }
        }    
    }     
    else                  
    {
         printf("Error\n");
    }
}

记住argv[1] 是一个字符串,即。一个字符数组(末尾有一个空字符)。

所以你必须遍历这个数组的所有字符。

编辑:chmike 在另一个答案中的好评。

【讨论】:

  • 我明白了!那么为什么要将 [k] 添加到 argv[1] 中呢?那有什么作用?
  • 表示数组 argv[1] 中的元素编号 k。例如如果 argv[1] = "123a", argv[1][0] = 1, argv[1][3] = a, 等等...
  • Nitpick:(char)0NUL 并且(可能)(void *)0NULL
  • @FiddlingBits,我不明白。字符 0 编码为十进制值 48。
  • 我不是说'0',我是说0
【解决方案2】:

for (int x = 0; x &lt; strlen(argv[1]); x++) 的开头不错,不幸的是它不适用于 C。

在 C 中,字符串以特殊字符 '\0' 结束。函数strlen 计算从字符串开头到这个特殊字符的字符。因此,当您编写for (int x = 0; x &lt; strlen(argv[1]); x++) 时,会在x 的每个测试中执行strlen()

这是避免这种情况的一种方法:

 for (int x = 0, n = strlen(argv[1]); x < n; x++)

这声明i初始化为0,n初始化为argv[1]的长度。该测试将x 与快速的n 进行比较。

另一种测试是否到达字符串末尾的方法是测试我们是否到达了那个特殊字符'\0'。

 for (int x = 0; argv[1][x] != '\0'; x++)

它们都是等价的。做你的选择。

现在,对于您要测试的每个字符是否为数字。您可以使用为您完成这项工作的函数 isdigit()。或者您可以自己编写测试,这并不难。

for (int x = 0, n = strlen(argv[1]); x < n; x++)
    if (!isdigit(argv[1][x])) {
        printf("failure: argv[1] is not all digits\n");
        return;
    }
printf("success: argv[1] is all digits\n")

我们自己实现的替代测试是这样的

for (int x = 0, n = strlen(argv[1]); x < n; x++)
    if (argv[1][x] < '0' || argv[1][x] > '9') {
        printf("failure: argv[1] is not all digits\n");
        return;
    }
printf("success: argv[1] is all digits\n")

请注意,argv[1][x] 包含字符的 ASCII 码,而“0”是 0 的 ASCII 码。另请注意,数字的 ASCII 码在“0”到“9”的范围内,此范围包含只有数字。这就是为什么上面的测试会测试argv[1][x] 是否不是数字。

【讨论】:

  • 谢谢!因此,在大家的帮助下,我能够让它识别正数和负数,但是当我输入 5x 时,它会吐出错误消息,这很好,但它也会打印出成功消息。有什么想法为什么会发生这种情况?
【解决方案3】:

您可以使用一些辅助函数来检查字符串是否由所有数字组成。

/* Return pointer to first non-digit character in a string. */
const char *findnondigit(const char *input)
{
    while (*input >= '0' && *input <= '9')
    {
        input++;
    }
    return input;
}

/* Return 1 if string is all digits, or 0 if it contains a non-digit. */
int checkalldigits(const char *input)
{
    /* Find first non-digit character in input. */
    input = findnondigit(input);
    /* Return whether first non-digit character is the string's null terminator. */
    return *input == '\0';
}

例如:

int main(int argc, char *argv[])
{
    if (argc > 1)
    {
        if (checkalldigits(argv[1]))
        {
            printf("%s is all digits\n", argv[1]);
        }
    }
}

【讨论】:

  • 是的,它是用C编写的。如果你需要使用cs50的string类型(实际上只是一个char *),那么你可以将const char *替换为string。 (const 也只允许函数在只读字符串上工作,但不是必需的。cs50 不提供与 const char * 完全等效的值,但在这种情况下,它最接近的等效值 string 可以。)
  • 此外,如果需要,您可以将测试 *input &gt;= '0' &amp;&amp; *input &lt;= '9' 替换为简单的 isdigit(*input)。从技术上讲,isdigit 如果没有额外的范围检查是不安全的,但对于 cs50 级别的专业知识来说应该没问题。
  • 我能够让它识别输入是正数还是负数,但是如果我在输入中添加一个字母,例如 5x,它会给我错误提示,这很好,但它也给了我成功提示。知道为什么会发生这种情况吗?
猜你喜欢
  • 1970-01-01
  • 2022-01-19
  • 1970-01-01
  • 2020-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-03
相关资源
最近更新 更多