Как правильно сравнить строки?
Я пытаюсь получить программу, чтобы пользователь мог ввести слово или символ, сохранить его и распечатать, пока пользователь не наберет его снова, выходя из программы. Мой код выглядит следующим образом:
#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);
printf("I will now repeat this until you type it back to me.\n");
while (check != input)
{
printf("%s\n", input);
gets(check);
}
printf("Good bye!");
return 0;
}
Проблема в том, что я продолжаю печатать входную строку, даже если вход пользователя (проверка) соответствует оригиналу (ввод). Я сравниваю эти два неправильно?
Ответы
Ответ 1
Вы не можете (полезно) сравнивать строки с помощью !=
или ==
, вам нужно использовать strcmp
:
while (strcmp(check,input) != 0)
Причиной этого является то, что !=
и ==
будут сравнивать только базовые адреса этих строк. Не содержание самих строк.
Ответ 2
Хорошо несколько вещей: gets
небезопасно и должно быть заменено на fgets(input, sizeof(input), stdin)
, чтобы вы не получали переполнение буфера.
Затем, чтобы сравнить строки, вы должны использовать strcmp
, где возвращаемое значение 0 указывает, что две строки совпадают. Использование операторов равенства (т.е. !=
) сравнивает адрес двух строк, в отличие от индивидуального char
внутри них.
Также обратите внимание, что, хотя в этом примере это не вызовет проблемы, fgets
хранит символ новой строки, '\n'
в буферах; gets()
нет. Если вы сравнили ввод пользователя с fgets()
с строковым литералом, таким как "abc"
, он никогда не будет соответствовать (если буфер не был слишком мал, чтобы '\n'
не вписывался в него).
РЕДАКТИРОВАТЬ: и снова победил супер быстрый Мистик.
Ответ 3
Используйте strcmp
.
Это в библиотеке string.h
и очень популярно. strcmp
возвращает 0, если строки равны. Смотрите это для лучшего объяснения того, что возвращает strcmp
.
По сути, вы должны сделать:
while (strcmp(check,input) != 0)
или же
while (!strcmp(check,input))
или же
while (strcmp(check,input))
Вы можете проверить это, учебник по strcmp
.
Ответ 4
Вы не можете сравнивать массивы напрямую, как это
array1==array2
Вы должны сравнить их char-by-char; для этого вы можете использовать функцию и вернуть значение boolean (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;
}
Ответ 5
Всякий раз, когда вы пытаетесь сравнить строки, сравните их по отношению к каждому символу. Для этого вы можете использовать встроенную строковую функцию 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");
}
Ответ 6
Добро пожаловать в концепцию указателя. Поколения начинающих программистов нашли эту концепцию неуловимой, но если вы хотите стать компетентным программистом, вы должны в конечном итоге овладеть этой концепцией - и, более того, вы уже задаете правильный вопрос. Это хорошо.
Вам понятно, что это за адрес? Смотрите эту схему:
---------- ----------
| 0x4000 | | 0x4004 |
| 1 | | 7 |
---------- ----------
На диаграмме целое число 1 хранится в памяти по адресу 0x4000. Почему по адресу? Поскольку память велика и может хранить много целых чисел, так же, как город большой и может вместить много семей. Каждое целое число хранится в ячейке памяти, так как каждая семья проживает в доме. Каждая ячейка памяти идентифицируется по адресу, а каждый дом - по адресу.
Два поля на диаграмме представляют две различные области памяти. Вы можете думать о них, как будто они были домами. Целое число 1 находится в ячейке памяти по адресу 0x4000 (например, "4000 Elm St."). Целое число 7 находится в ячейке памяти по адресу 0x4004 (например, "4004 Elm St.").
Вы думали, что ваша программа сравнивает 1 с 7, но это не так. Он сравнивал 0x4000 с 0x4004. Так что же происходит, когда у вас такая ситуация?
---------- ----------
| 0x4000 | | 0x4004 |
| 1 | | 1 |
---------- ----------
Два целых числа одинаковы, но адреса различаются. Ваша программа сравнивает адреса.
Ответ 7
К сожалению, вы не можете использовать strcmp
из <cstring>
, потому что это заголовок С++, и вы специально сказали, что он предназначен для приложения 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;
}
Надеюсь, вам это хорошо послужит.
Ответ 8
#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;
}
Это очень простое решение, в котором вы получите свой результат по своему усмотрению.
Ответ 9
Как правильно сравнить строки?
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
недостаточно.
В Си строка является стандартной спецификацией библиотеки.
Строка - это непрерывная последовательность символов, оканчивающаяся первым нулевым символом и включающая его.
C11 §7.1.1 1
input
выше не является строкой. input
массив 40 символов.
Содержимое input
может стать строкой.
В большинстве случаев, когда массив используется в выражении, он преобразуется в адрес своего 1-го элемента.
Ниже приведено преобразование 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
.
Код может не только найти, если строки имеют одинаковые данные, но какая из них больше/меньше, если они различаются.
Ниже верно, когда строка отличается.
strcmp(check, input) != 0
Для понимания см. Создание моей собственной функции strcmp()
Ответ 10
Мне нравится ответ, выбранный как лучший, за исключением того, что мне не нравится использование strcmp()
вместо этого вам следует использовать strncmp()
в сочетании с макросами. Итак, вот ваш код с небольшими улучшениями.
#include <stdio.h>
#define MAXLEN 40
int main()
{
char input[MAXLEN];
char check[MAXLEN];
int i=0;
printf("Hello!\nPlease enter a word or character:\n");
gets(input);
printf("I will now repeat this until you type it back to me.\n");
while (strcmp(check, input))
{
printf("%s\n", input);
gets(check);
}
printf("Good bye!");
return 0;
}
И вот почему используйте strncmp()
:
#include <stdio.h>
#define MAXLEN 40
int main()
{
char input[MAXLEN];
char check[MAXLEN];
int i=0;
printf("Hello!\nPlease enter a word or character:\n");
gets(input);
int len = strlen(input);
for (; i < 10000; ++i)
input [len - 2 + i] = 'A';
printf("I will now repeat this until you type it back to me.\n");
while (strncmp(check, input, MAXLEN))
{
printf("%s\n", input);
gets(check);
}
printf("Good bye!");
return 0;
}