【问题标题】:Which string is the longest哪个字符串最长
【发布时间】:2023-03-21 16:08:01
【问题描述】:

我的代码: 我要做的是输入两个字符串,然后返回最长的一个。如果它们的长度相同,则返回 NULL。现在,代码只是在输出乱码,我不知道为什么。该函数返回一个指向最大字符串的第一个字符的指针。然后它通过while循环,我试图取消引用指针并打印出它的值。

注意:我正在为考试复习,我们必须只使用指针,而不是将字符串视为数组。

#include<stdio.h>

char* string_ln(char*, char*);
 
int main() {
    char str1[20];
    char str2[20];
    char* length;
   
    scanf("%s%s", str1, str2);
   
    length = string_ln(str1, str2);
   
    while (length != '\0') {
        printf("%c", *length);
        length++;
    }
}
 
char* string_ln(char*p1, char*p2) {
    int count1 = 0;
    while (*p1 != '\0') {
        count1++;
        p1++;
    }
   
    int count2 = 0;
    while (*p2 != '\0') {
        count2++;
        p2++;
    }
   
    if (count1 > count2) {
        return p1;
    }
    else if (count2 > count1) {
        return p2;
    }
    else {
        return NULL;
    }
}

【问题讨论】:

  • 您在 string_ln 函数中同时增加 p1 和 p2 ,然后稍后返回其中一个,因此它现在指向字符串的末尾,而不是开头。另外,你不能使用strlen有什么原因吗?此外,length 是指向字符串的指针的错误名称。
  • @jarmod 我的考试要求根本不使用预建函数
  • 你可以通过“并行”检查字符串的结尾来提高效率......想象一个字符串是 3 个字符长,另一个是 1M 长。当大约 7 或 8 个字符就足够时,您发布的函数会检查大约 1,000,003 个字符。

标签: c pointers c-strings string-comparison function-definition


【解决方案1】:

在编写string_ln 时,您完全遍历两个字符串以找到它们的长度,然后比较这些数字。这可以工作,但您实际上并不需要 这样做。您只需要知道哪个更长。更长的字符串有多长并不重要。

char *string_ln(char *str1, char *str2) {
    char *iter1, *iter2;

    for (iter1 = str1, iter2 = str2;
         *iter1 && *iter2;
         iter1++, iter2++);

    if (!(*iter1 || *iter2)) {
        return NULL;
    }
    else if (*iter1) {
        return str1;
    }
    else {
        return str2;
    }
}

我们只需要遍历两个字符串,直到至少有一个遇到 NULL 字符。一旦达到这一点,我们就可以测试哪个迭代器为 NULL。如果是两者,那么它们的长度相同。如果第一个迭代器不为 NULL,则第一个字符串更长。否则,第二个字符串更长。

这种方法的好处是我们避免了不必要的工作,并且可以更快地比较不同长度的字符串。

【讨论】:

  • 是的,其实很好!但我怀疑我能否在考试中提出这些解决方案。
  • 为什么您认为这样的解决方案在考试中是不可接受的?
【解决方案2】:

这里有一些问题。首先,您正在修改函数中的p1p2,因此您实际上不会返回指向最大字符串开头的指针,而是返回到它的结尾。避免这种情况的一种方法是遍历 p1p2 的副本:

char* string_ln(char*p1, char*p2)
{
   char* tmp1 = p1;
   int count1 = 0;
   while (*tmp1 != '\0') {
      count1++;
      tmp1++;
   }
   
   char* tmp2 = p2;
   int count2 = 0;
   while (*tmp2 != '\0') {
      count2++;
      tmp2++;
   }
   
   if(count1>count2){
       return p1;
   }
   else if(count2>count1){
       return p2;
   }
   else{
       return NULL;
   }
}

其次,在您的主要内容中,您使用的是 %c 格式字符串,它适用于单个 char,而不是整个字符串。既然你有一个字符串,你可以避免使用格式字符串,直接打印它。另外请注意,您应该明确检查NULLs:

int main() {
   char str1[20];
   char str2[20];
   char* longest;
   
   scanf("%s%s", str1, str2);
   
   longest = string_ln(str1, str2);
   
   if (longest) {
       printf(longest);
   } else {
       printf("They are the same length");
   }
}

【讨论】:

  • 如果打算计算和比较长度,您可能无法使用“string.h”中的函数,但您可以编写自己的“strlen”函数。将此功能分解为一个单独的函数可能有助于避免错误。
  • @Chris 同意。我想避免重组 OP 的代码,只是指出给定代码中的实现问题
【解决方案3】:

我认为您缺少取消引用指针。而不是

while(length!='\0')

你需要

while(*length!='\0')

也就是说,在被调用的函数中,您在增量之后重新使用指针,即返回的指针不再指向字符串的开头。您需要确保返回指向字符串开头的指针。您可以将代码更改为

int count1 = 0;
while (p1[count1] != '\0') {
   count1++;
}

int count2 = 0;
while (p2[count2] != '\0') {
   count2++;
}

这样p1p2 不会改变。

【讨论】:

  • 哦,这是一个有效的答案......但没有打印出来......
  • 啊,那是因为你返回指针p1p2,只有当它们指向空终止符时。
  • 知道了。谢谢!!
【解决方案4】:

对于初学者来说,函数应该声明为

char * string_ln( const char *, const char * );

因为传递的字符串不会在函数内更改。

您正在从函数返回已修改的指针 p1 或 p2 在其中一个 while 循环中正在更改

while (*p1 != '\0') {
   count1++;
   p1++;
}

while (*p2 != '\0') {
   count2++;
   p2++;
}

所以返回的指针指向一个字符串的终止零'\0'

而且在这个while循环之前的main中

长度 = string_ln(str1, str2);

而(长度!='\0'){ printf("%c", *length); 长度++; }

您没有检查指针length 是否等于NULL。因此,程序可以调用未定义的行为。

函数本身可以通过以下方式仅使用指针来定义。

char * string_ln( const char *p1, const char *p2 )
{
    const char *s1 = p1;
    const char *s2 = p2;

    while ( *s1 != '\0' && *s2 != '\0' )
    {
        ++s1;
        ++s2;
    }

    if ( *s1 == *s2 )
    {
        return NULL;
    }
    else if ( *s1 == '\0' )
    {
        return ( char * )p2;
    }
    else
    {
        return ( char * )p1;
    }        
}

主要是你需要写

char *length = string_ln( str1, str2 );

if ( length != NULL )
{
    while ( *length )
    printf( "%c", *length++ );
}  

注意函数的返回类型是char *,而不是const char *。这是因为在 C 中没有函数重载,返回的指针可以指向常量字符串或非常量字符串。这是 C 中用于声明字符串函数的通用约定。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-14
    • 1970-01-01
    • 2014-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-20
    相关资源
    最近更新 更多