繁体   English   中英

如何正确比较 C 中的字符串?

[英]How do I properly compare strings in C?

我试图让一个程序让用户输入一个单词或字符,存储它,然后打印它直到用户再次键入它,退出程序。 我的代码如下所示:

#include <stdio.h>

int main()
{
    char input[40];
    char check[40];
    int i=0;
    printf("Hello!\nPlease enter a word or character:\n");
    gets(input);   /* obsolete function: do not use!! */
    printf("I will now repeat this until you type it back to me.\n");

    while (check != input)
    {
        printf("%s\n", input);
        gets(check);   /* obsolete function: do not use!! */
    }

    printf("Good bye!");
    

    return 0;
}

问题是我一直在打印输入字符串,即使用户输入(检查)与原始输入(输入)匹配。 我是否错误地比较了两者?

您不能(有用地)使用!===比较字符串,您需要使用strcmp

while (strcmp(check,input) != 0)

这样做的原因是因为!===只会比较这些字符串的基地址。 不是字符串本身的内容。

好的一些事情: gets是不安全的,应该用fgets(input, sizeof(input), stdin)替换,这样你就不会遇到缓冲区溢出。

接下来,要比较字符串,您必须使用strcmp ,其中返回值 0 表示两个字符串匹配。 使用相等运算符(即!= )比较两个字符串的地址,而不是其中的单个char

还要注意,虽然在这个例子中它不会引起问题,但fgets也将换行符'\n'存储在缓冲区中; gets()没有。 如果您将来自fgets()的用户输入与诸如"abc"之类的字符串文字进行比较,它将永远不会匹配(除非缓冲区太小以至于'\n'不适合它)。

使用strcmp

这是在string.h库中,非常受欢迎。 如果字符串相等, strcmp返回 0。 有关strcmp返回的内容的更好解释,请参阅内容。

基本上,你必须这样做:

while (strcmp(check,input) != 0)

或者

while (!strcmp(check,input))

或者

while (strcmp(check,input))

你可以查看这个,关于strcmp的教程。

你不能像这样直接比较数组

array1==array2

您应该逐个字符地比较它们; 为此,您可以使用一个函数并返回一个布尔 (True:1, False:0) 值。 然后你可以在while循环的测试条件中使用它。

尝试这个:

#include <stdio.h>
int checker(char input[],char check[]);
int main()
{
    char input[40];
    char check[40];
    int i=0;
    printf("Hello!\nPlease enter a word or character:\n");
    scanf("%s",input);
    printf("I will now repeat this until you type it back to me.\n");
    scanf("%s",check);

    while (!checker(input,check))
    {
        printf("%s\n", input);
        scanf("%s",check);
    }

    printf("Good bye!");

    return 0;
}

int checker(char input[],char check[])
{
    int i,result=1;
    for(i=0; input[i]!='\0' || check[i]!='\0'; i++) {
        if(input[i] != check[i]) {
            result=0;
            break;
        }
    }
    return result;
}

每当您尝试比较字符串时,请针对每个字符进行比较。 为此,您可以使用名为 strcmp(input1,input2); 的内置字符串函数。 你应该使用名为#include<string.h>的头文件

试试这个代码:

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

int main() 
{ 
    char s[]="STACKOVERFLOW";
    char s1[200];
    printf("Enter the string to be checked\n");//enter the input string
    scanf("%s",s1);
    if(strcmp(s,s1)==0)//compare both the strings  
    {
        printf("Both the Strings match\n"); 
    } 
    else
    {
        printf("Entered String does not match\n");  
    } 
    system("pause");  
} 

欢迎来到指针的概念。 一代又一代的初级程序员发现这个概念难以捉摸,但如果你想成长为一名称职的程序员,你必须最终掌握这个概念——而且,你已经问对了问题。 那挺好的。

你清楚什么是地址吗? 看这张图:

----------     ----------
| 0x4000 |     | 0x4004 |
|    1   |     |    7   |
----------     ----------

在图中,整数 1 存储在内存中的地址0x4000。 为什么在一个地址? 因为内存很大,可以存储很多整数,就像一个城市很大,可以容纳很多家庭一样。 每个整数都存储在一个内存位置,因为每个家庭都住在一个房子里。 每个内存位置都由一个地址标识,就像每个房子都由一个地址标识一样。

图中的两个框代表两个不同的内存位置。 你可以把它们想象成房子。 整数 1 位于地址 0x4000 的内存位置(想想“4000 Elm St.”)。 整数 7 位于地址 0x4004 的内存位置(想想“4004 Elm St.”)。

您认为您的程序将 1 与 7 进行比较,但事实并非如此。 它正在比较 0x4000 和 0x4004。 那么当你遇到这种情况时会发生什么?

----------     ----------
| 0x4000 |     | 0x4004 |
|    1   |     |    1   |
----------     ----------

这两个整数相同,但地址不同。 您的程序比较地址。

如何正确比较字符串?

char input[40];
char check[40];
strcpy(input, "Hello"); // input assigned somehow
strcpy(check, "Hello"); // check assigned somehow

// insufficient
while (check != input)

// good
while (strcmp(check, input) != 0)
// or 
while (strcmp(check, input))

让我们更深入地了解为什么check != input是不够的。

在 C 中,字符串是标准库规范。

字符串是由第一个空字符终止并包括第一个空字符的连续字符序列。
C11 §7.1.1 1

上面的input不是字符串 inputchar 的数组 40

input的内容可以变成一个字符串

在大多数情况下,当在表达式中使用数组时,它会被转换为其第一个元素的地址。

下面将checkinput转换为它们各自的第一个元素的地址,然后比较这些地址。

check != input   // Compare addresses, not the contents of what addresses reference

要比较字符串,我们需要使用这些地址,然后查看它们指向的数据。
strcmp()完成这项工作 §7.23.4.2

int strcmp(const char *s1, const char *s2);

strcmp函数将s1指向的字符串与s2指向的字符串进行比较。

strcmp函数返回一个大于、等于或小于零的整数,相应地,因为s1指向的字符串大于、等于或小于s2指向的字符串。

代码不仅可以查找字符串是否具有相同的数据,而且当它们不同时哪个更大/更少。

当字符串不同时,以下情况为真。

strcmp(check, input) != 0

如需深入了解,请参阅创建我自己的strcmp()函数

您需要使用strcmp()并且需要#include <string.h>

!===运算符仅比较这些字符串的基地址。 不是字符串的内容

while (strcmp(check, input))

示例代码:

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

int main()
{
    char input[40];
    char check[40] = "end\n"; //dont forget to check for \n

    while ( strcmp(check, input) ) //strcmp returns 0 if equal
    {
        printf("Please enter a name: \n");
        fgets(input, sizeof(input), stdin);
        printf("My name is: %s\n", input);
    }

    printf("Good bye!");
    return 0;
}

注意1: gets()是不安全的。 改用fgets()

注意2:使用fgets()时,您还需要检查'\n'换行符

你可以:

使用string.h中的strcmp() ,这是更简单的版本

或者如果你想自己动手,你可以使用这样的东西:

int strcmp(char *s1, char *s2)
{
    int i;
    while(s1[i] != '\0' && s2[i] != '\0')
    {
        if(s1[i] != s2[i])
        {
            return 1;
        }
        i++;
    }
    return 0;
}

我会以这样的方式使用strcmp()

while(strcmp(check, input))
{
    // code here
}

不幸的是,您不能使用<cstring> strcmp ,因为它是C ++头文件,并且您专门说过它是针对C应用程序的。 我遇到了同样的问题,所以我不得不编写自己的函数来实现strcmp

int strcmp(char input[], char check[])
{
    for (int i = 0;; i++)
    {
        if (input[i] == '\0' && check[i] == '\0')
        {
            break;
        }
        else if (input[i] == '\0' && check[i] != '\0')
        {
            return 1;
        }
        else if (input[i] != '\0' && check[i] == '\0')
        {
            return -1;
        }
        else if (input[i] > check[i])
        {
            return 1;
        }
        else if (input[i] < check[i])
        {
            return -1;
        }
        else
        {
            // characters are the same - continue and check next
        }
    }
    return 0;
}

希望这对您有帮助。

    #include<stdio.h>
    #include<string.h>
    int main()
    {
        char s1[50],s2[50];
        printf("Enter the character of strings: ");
        gets(s1);
        printf("\nEnter different character of string to repeat: \n");
        while(strcmp(s1,s2))
        {
            printf("%s\n",s1);
            gets(s2);
        }
        return 0;
    }

这是一个非常简单的解决方案,您可以根据需要获得输出。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM