【问题标题】:How does this function that verify if a informed name is equal to other name works验证知情名称是否等于其他名称的此功能如何工作
【发布时间】:2021-11-17 01:22:51
【问题描述】:

我一直在寻找验证两个字符串是否相等的 C 代码。我找到了这个,但我不明白forwhile 部分的逻辑。

int verify(phonebook name[],char name_verify[])
{
    int i,k;

    char *p,temp[strlen(name_verify)];

    if(strlen(name) >= strlen(name_verify))
    {
        for(i=0; i<=(strlen(name) - strlen(name_verify)) ; i++)
        {
            p=&name[i];
            k=0;
            
            while(k!=strlen(name_verify))
            {
                temp[k] =* (p + k);
                k++;
            }
            temp[k]='\0';

            if(strcmp(strupr(temp),strupr(name_verify))==0)
            {
                return 1;
            }
        }
    }

有人可以向我解释一下它是如何工作的吗?

【问题讨论】:

  • 代码检查字符串name_verify是否是字符串name的子字符串,与字母大小写无关。
  • 你能解释一下为什么这段代码不好吗?
  • 至少因为函数 strlen 被多次调用相同的字符串。还有一些未在使用它们的范围内声明的已使用变量。而且数组 temp 是多余的。
  • @VladfromMoscow 这部分是如何工作的temp[k] =* (p + k); 我没明白,因为 p 是一种 char 指针类型,它与整数类型求和。
  • 同 temp[k] = p[k];其中指针 p 指向从索引 i 开始的字符串名称的子字符串。

标签: c substring c-strings function-definition


【解决方案1】:

首先是函数的声明

int verify(phonebook name[],char name_verify[])

令人困惑,因为不清楚类型说明符phonebook 的含义。所以函数的读者需要研究函数体,假设phonebookchar类型的同义词。

这个变长数组的声明

char *p,temp[strlen(name_verify)];

可能是未定义行为的原因,因为它没有空间来存储字符串 name_verify 的终止零字符“\0”。

你必须写

char *p,temp[strlen(name_verify) + 1];

但是使用可变长度数组可能是堆栈溢出的原因。使用这个数组是完全多余的。没有它也可以编写函数。

在函数内有大量对函数strlen的冗余调用。

该函数尝试检查字符串 name 自身是否包含与字符串 name_verify 相等的子字符串,如果将两者都转换为大写。

函数首先检查字符串name的长度是否不小于字符串name_verify的长度。

if(strlen(name) >= strlen(name_verify))

然后在for循环中

for(i=0; i<=(strlen(name) - strlen(name_verify)) ; i++)

开始遍历字符串name,判断字符串name中从索引i开始的子字符串是否等于字符串name_verify。

为此,将字符串名称的子字符串复制到数组 temp 中

        p=&name[i];
        k=0;
        
        while(k!=strlen(name_verify))
        {
            temp[k] =* (p + k);
            k++;
        }
        temp[k]='\0';

复制完成后,将数组 temp 中形成的字符串以大写形式与字符串 name_verify 进行比较。

        if(strcmp(strupr(temp),strupr(name_verify))==0)
        {
            return 1;
        }

如果它们相等,则函数返回 1。

否则,如果字符串name 中没有这样的子字符串等于name_verify,则该函数似乎在返回语句中返回0,而提供的代码中未显示。:)

【讨论】:

    【解决方案2】:

    关于“这是一个糟糕的代码”,我想说的主要原因是它的功能过于复杂,以至于我可以相信它被故意混淆了,而且它没有使用明显的标准库函数。为了演示,这是我编写函数的一种方式:

    int verify(const char name[], char name_verify[]) {
        char temp = strdup(name);
        int result = ((strstr(strupr(temp), strupr(name_verify))) != NULL);
    
        free(temp);
        return result ;
    }
    

    这(太多了!)更清晰更清晰。

    如果您碰巧没有strdup()(由 POSIX 指定,而不是 C 语言规范),那么您始终可以实现自己的:

    char *strdup(const char *src) {
        char *result = malloc(strlen(src) + 1);
    
        if (result) {
            strcpy(result, src);
        }
    
        return result;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-29
      • 2014-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-21
      • 2023-03-04
      • 2016-02-18
      相关资源
      最近更新 更多