比较字符串的结尾

3

我正在编写一个程序来比较不同的字符串,特别是以 OH 结尾的化学元素。如果字符串以 OH 结尾,我必须返回 -1。然而,我的程序没有正常工作。我错在哪里了?

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

int hydroxide(char *string);

int main() {
    char *string;
    printf("Enter String:");
    gets(string);
    printf("%d", hydroxide(string));
}

int hydroxide(char *string) {
    string = strrchr(string, 'O');
    if (string != NULL)
        return (strcmp(string, "OH"));
    return (-1);
 }

1
小贴士:避免使用 gets() - 它是一个不良的编程实践和已被弃用的函数。 - Rohan Bari
@brogrammer 为什么这个函数返回-1而不是1?通常1表示真,0表示假。或者-1表示小于0等于0,1表示大于0。 - Vlad from Moscow
3个回答

1
你的函数太过复杂,而且如果后缀是“OH”它会返回0。一个更简单的方法是计算字符串长度,如果长度至少为2,则比较最后两个字符是否为“O”和“H”。保留HTML标签。
int hydroxide(const char *string) {
    size_t len = strlen(string);
    if (len >= 2 && string[len - 2] == 'O'  && string[len - 1] == 'H')
        return -1;
    else
        return 0;
}

此外,main函数存在未定义行为: string 是一个未初始化的 char 指针:将其传递给 gets() 会导致未定义行为,因为 gets() 尝试写入字节时会导致缓冲区溢出。还要注意,gets() 已经过时,并在最新版本的 C 标准中被删除,因为对于足够长的输入字符串,没有办法防止缓冲区溢出。使用 fgets() 替代并删除结尾的换行符:

以下是修改后的版本:

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

int hydroxide(const char *string) {
    size_t len = strlen(string);
    if (len >= 2 && string[len - 2] == 'O'  && string[len - 1] == 'H')
        return -1;
    else
        return 0;
}

int main() {
    char buf[80];
    printf("Enter String: ");
    if (fgets(buf, sizeof buf, stdin)) {
        buf[strcspn(buf, "\n")] = '\0';  // strip the newline if any
        printf("%d\n", hydroxide(string));
    }
    return 0;
}

1
首先,该函数的逻辑是错误的。 通常这样的函数应该返回 1(或正值),对应于逻辑上的true0,对应于逻辑上的false,当它回答像“是或否”的问题时。 此调用
strcmp(string, "OH")

如果两个字符串相等,返回0。否则,该函数可以返回任何正数或负数,具体取决于第一个字符串是大于还是小于第二个字符串。

除此之外,函数参数应该有限定符const,因为传递的字符串在函数内部不会被更改。

您没有预留内存来读取字符串。声明的指针

char *string;

变量未初始化且其值不确定。因此,此调用

gets(string);

调用未定义的行为。

请注意,函数gets是一种不安全的函数,不受C标准支持。相反,您应该使用标准的C函数fgets

如果函数更通用将会更好。也就是说,它可以检查任何提供的字符串后缀。始终尝试编写更通用的函数。在这种情况下,它们可以重复使用。

下面是一个演示程序,展示了如何定义该函数。

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

int hydroxide( const char *s, const char *suffix )
{
    size_t n1 = strlen( s );
    size_t n2 = strlen( suffix );

    return !( n1 < n2 ) && strcmp( s + n1 - n2, suffix )  == 0;
 }

int main(void) 
{
    enum { N = 100 };
    char s[N];

    while ( 1 )
    {
        printf( "Enter a String (empty string - exit): " );

        if ( fgets( s, N, stdin ) == NULL || s[0] == '\n' ) break;

        s[ strcspn( s, "\n" ) ] = '\0';

        printf( "%s\n", hydroxide( s, "OH" ) ? "true" : "false" );
    }

    return 0;
}

程序的输出可能看起来像这样:
Enter a String (empty string - exit): brogrammerOH
true
Enter a String (empty string - exit): 

0

获取字符串长度并检查最后两个字符。

int len = strlen(string);
      if(string[len-1] == 'H' && string[len-2] =='O')
          return -1;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接