【问题标题】:comparing the ending of the strings比较字符串的结尾
【发布时间】:2020-08-25 11:01:08
【问题描述】:

我正在编写一个程序来比较不同的字符串。特别是以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);
 }

【问题讨论】:

  • 小贴士:避免使用gets() - 这是一种不好的做法,并且已被弃用。
  • @brogrammer 为什么函数返回 -1 而不是 1?!通常 1 表示真,0 表示假。或 -1 表示小于 0 等于和大于 1。

标签: c c-strings strcmp suffix function-definition


【解决方案1】:

对于初学者来说,函数的逻辑是错误的。

通常,这样的函数在回答“是或否”之类的问题时,应返回对应于逻辑true1(或正值)或对应于逻辑false0 .

这个电话

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): 

【讨论】:

    【解决方案2】:

    你的函数太复杂了,如果后缀是OH,它会返回0。更简单的方法是计算字符串的长度,如果该长度至少为 2,则将最后 2 个字符与 'O''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;
    }
    

    此外,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;
    }
    

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-08-28
        • 1970-01-01
        • 2013-05-06
        • 1970-01-01
        • 2021-08-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多