提问人:nmagerko 提问时间:11/4/2011 最后编辑:chqrlienmagerko 更新时间:8/11/2023 访问量:641032
如何在 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;
}
问题是,即使用户()的输入与原始()匹配,我也会不断打印输入字符串。我是否错误地比较了两者?check
input
答:
你不能(有用地)使用 或 比较字符串,你需要使用:!=
==
strcmp
while (strcmp(check,input) != 0)
这样做的原因是,并且只会比较这些字符串的基址。不是字符串本身的内容。!=
==
评论
while (strcmp(check, input))
buffer[strlen(buffer) - 1] = '\0';
fgets()
fgets()
buffer[strlen(buffer) - 1] = '\0';
好的几件事:gets
是不安全的,应该被替换,这样你就不会得到缓冲区溢出。fgets(input, sizeof(input), stdin)
接下来,要比较字符串,必须使用 ,其中返回值为 0 表示两个字符串匹配。使用相等运算符 (ie.) 比较两个字符串的地址,而不是其中的单个 s。strcmp
!=
char
还要注意的是,虽然在此示例中它不会造成问题,但将换行符也存储在缓冲区中; 不。如果将用户输入与字符串文本进行比较,则它永远不会匹配(除非缓冲区太小,因此无法放入其中)。fgets
'\n'
gets()
fgets()
"abc"
'\n'
评论
fgets()
"abc\n"
fgets()
"abc"
"abc"
buffer[strcspn(buffer, "\n")] = '\0';
你不能像这样直接比较数组
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;
}
评论
checker
'\0'
'\0'
1
"foo"
"foobar"
||
&&
使用 strcmp
。
这在图书馆里,非常受欢迎。 如果字符串相等,则返回 0。有关返回内容的更好解释,请参阅此内容。string.h
strcmp
strcmp
基本上,您必须执行以下操作:
while (strcmp(check,input) != 0)
或
while (!strcmp(check,input))
或
while (strcmp(check,input))
您可以查看此教程。strcmp
每当您尝试比较字符串时,请将它们与每个字符进行比较。为此,您可以使用名为 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");
}
#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;
}
这是一个非常简单的解决方案,您可以在其中获得所需的输出。
评论
gets();
自 C11 以来,它不是标准 C 的一部分。
strcmp(s1,s2)
是 UB,因为一开始没有指定内容。s2
如何正确比较字符串?
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 != 输入
不够。
在 C 语言中,字符串是标准的库规范。
字符串是以第一个 null 字符结尾并包含第一个 null 字符的连续字符序列。
C11 §7.1.1 1
input
上面不是字符串。 是 char 的数组 40。input
的内容可以变成字符串。input
在大多数情况下,当在表达式中使用数组时,它会转换为其第一个元素的地址。
下面的 和 转换为第一个元素的各自地址,然后比较这些地址。check
input
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
代码不仅可以发现字符串是否具有相同的数据,还可以发现当它们不同时哪个更大/更小。
当字符串不同时,以下情况为 true。
strcmp(check, input) != 0
有关见解,请参阅创建我自己的 strcmp()
函数
欢迎来到指针的概念。一代又一代的初级程序员发现这个概念难以捉摸,但如果你想成长为一个称职的程序员,你必须最终掌握这个概念——而且,你已经问了正确的问题。很好。
你清楚地址是什么吗?请看下图:
---------- ----------
| 0x4000 | | 0x4004 |
| 1 | | 7 |
---------- ----------
在图中,整数 1 存储在内存中的地址 0x4000。为什么在地址?因为内存很大,可以存储很多整数,就像一个城市很大,可以容纳很多家庭一样。每个整数都存储在一个内存位置,因为每个家庭都住在一所房子里。每个内存位置都由一个地址标识,就像每个房屋由一个地址标识一样。
图中的两个框表示两个不同的内存位置。你可以把它们想象成房子。整数 1 位于地址 0x4000 的内存位置(例如“4000 Elm St.”)。整数 7 位于地址 0x4004 的内存位置(例如“4004 Elm St.”)。
您认为您的程序正在将 1 与 7 进行比较,但事实并非如此。它正在将0x4000与0x4004进行比较。那么当你遇到这种情况时会发生什么?
---------- ----------
| 0x4000 | | 0x4004 |
| 1 | | 1 |
---------- ----------
两个整数相同,但地址不同。您的程序会比较地址。
你需要使用,你需要strcmp()
#include <string.h>
and 运算符仅比较这些字符串的基址。不是字符串的内容!=
==
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'
您可以:
使用 from ,这是更简单的版本strcmp()
string.h
或者,如果你想自己滚动,你可以使用这样的东西:
int strcmp(const char *s1, const char *s2)
{
for (i = 0; s1[i] != '\0' || s2[i] != '\0'; i++)
{
if (s1[i] != s2[i])
{
return (unsigned char)s1[i] < (unsigned char)s2[i] ? -1 : 1;
}
}
return 0;
}
我会以这样的方式使用:strcmp()
while (strcmp(check, input))
{
// code here
}
评论
return 0;
strcmp
i
0
for
while
return
我刚刚开始编码并开始在 YouTube 上观看 CS50 视频。在那里我遇到了一个问题,您不能使用“==”比较两个字符串。所以我试了一下:
#include <iostream>
using namespace std;
int main()
{
string str[] = {"tom", "chris"};
if (str[0] == "tom")
{
return 0;
}
return 1;
}
由于某种原因,程序工作并返回 0。这里的视频和帖子另有说明。
评论
"tom"
char
strcmp()
评论
gets( )
已从标准中删除。请改用。fgets( )
strcmp()
在其输入相等时返回零的答案解释了如何比较字符串的相等性、不等式、小于、大于、小于或等于以及大于或等于。并非所有字符串比较都是为了相等。区分大小写的比较又不同了;其他特殊比较(例如字典顺序)需要更专业的比较器,并且还有用于更复杂比较的正则表达式。gets()