【问题标题】:Compare character by character 2 strings逐个字符比较 2 个字符串
【发布时间】:2016-06-03 19:11:13
【问题描述】:

我正在尝试编写一个程序来告诉我 2 个字符串是否相同。如果他们有一个不同的角色,他们就没有。

我有这个代码,但它不起作用,为什么?

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

int main() {
   char str1[30], str2[30];
   int i;

   printf("\nEnter two strings :");
   gets(str1);
   gets(str2);

for (i=0;str1[i]==str2[i];i++)
    if (str1[i]!=str2[i]){
        printf("They are not identical");
    }
    else continue;
    return (0);
}

它编译时出现 0 个错误和 0 个警告,但是当我引入 2 个不相同的字符串时,它什么也不返回。 (当我引入 2 个相同的字符串时也会发生同样的情况,但这是应该的)

我应该怎么做才能解决它?

【问题讨论】:

  • 只需以"A""B" 的简单情况,逐步执行您的程序,您就会看到。另外,请在此处发帖时注明您的姓名。
  • 旁白:请使用最新的材料:您使用的maingets 都已过时。

标签: c string compare


【解决方案1】:

这里有一个重要的错误。首先:经典的“c 风格字符串”是空终止的。尽管还有其他选择(例如将长度存储在字符串之外),但以 null 结尾的字符串是语言的一部分(因为代码中的字符串文字由编译器以 null 结尾),并且运行时库(大多数字符串函数处理 \ 0 在字符串的末尾)。

gets 还在输入字符串的末尾附加了一个 \0: http://www.cplusplus.com/reference/cstdio/gets/

您不仅要比较输入的字符串,还要比较内存中该字符串之后的任何内容(随机)。

应该是这样的:

for(int i=0;str1[i]==str2[i];i++){
 if(str1[i]==0) {
  printf("equal");
 }
}
printf("not equal");

还有其他选择,比如使用指针。但在现代编译器上,它们应该产生大致相同的机器代码。

请注意,有 C 运行时库函数来比较字符串:

strcmp是最基本的,就两个char *:

strncmp 允许指定要比较的最大字符数,比较字符串的一部分:

还有其他的,看看链接就行了。

请注意,最好使用库函数,因为即使在这样一个“简单”的函数中。有比较字符串的优化方法。就像比较原生字的大小一样。在 32 位平台上,您要多花四倍的时间进行比较,这还不包括执行字节操作所需的掩码。

【讨论】:

  • 详细说明:string 不是 C 语言的一部分,而是 C 标准库的一部分。 OTOH,String literals,C 语言的一部分,不是 always 以空字符结尾的。例如char a[4] = "bc" "cd"; 字符串文字 "bc" "cd" 都没有空字符。请注意,由于 C11,gets() 不是标准 C 的一部分。然而,UV 用于漂亮的简洁代码。
【解决方案2】:

您的for 循环是:

for (i=0;str1[i]==str2[i];i++)
  if (str1[i]!=str2[i]){
     printf("They are not identical");
  }
  else continue;

假设str1"abc"str2"xyz"

for 循环中的条件对于 i = 0 的计算结果为 false。因此,您将永远不会得到声明:

  if (str1[i]!=str2[i]){

因此,您将永远不会执行:

     printf("They are not identical");

您可以使用以下方法修复逻辑错误:

for (i=0; str1[i] != '\0' && str2[i] != '\0'; i++)
{
   if (str1[i]!=str2[i]) {
      break;
  }
}

// If at end of the loop, we have reached the ends 
// of both strings, then they are identical. If we
// haven't reached the end of at least one string,
// then they are not identical.
if ( str1[i] != '\0' || str2[i] != '\0' )
{
   printf("They are not identical");
}

【讨论】:

  • 字符串"abc""abcd" 不会被检测为不相等。更改为str1[i] != '\0' || str2[i] != '\0' 进行修复。
  • 可以简化为for (i=0; str1[i]; i++)。无需测试str2[],因为下一个测试if (str1[i]!=str2[i]) 会捕获`str2 中的空字符。
  • 你不需要最终测试,(而且我认为它不正确);您只需要更改原始代码中的循环测试。或者更简单——@chux 所说的。
【解决方案3】:

我有这个代码,但它不起作用,为什么? 因为您的循环条件str1[i]==str2[i] 将使内部if 条件始终为假。

我应该怎么做才能解决它? 简单代码:

for ( i=0; str1[i]==str2[i] && str1[i]!='\0'; i++) {
}
if ( str1[i]!=str2[i] ) {
    printf("They are not identical");
}

i=0;
while ( str1[i]==str2[i] && str1[i]!='\0' ) {
    i++;
}
if ( str1[i]!=str2[i] ) {
    printf("They are not identical");
}

【讨论】:

    【解决方案4】:

    假设您有两个字符串,其中第一个字符不同。那么你将不会进入循环,因为循环的条件 (str1[i]==str2[i]) 失败,因此条件应该是 (str1[i]!='\0' && str2[i]!= '\0' )。 '\0' 是 c 样式字符串的最后一个字符。 您还可以使用字符串内置函数,如“strcmp(str1,str2)”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-01-14
      • 2019-10-29
      • 1970-01-01
      • 2012-08-02
      • 1970-01-01
      • 2019-11-10
      • 1970-01-01
      相关资源
      最近更新 更多