У меня есть две строки. Допустим, str1="One Two Three"
и str2="two"
. Я хотел бы знать, есть ли какая-либо функция, которая проверяет соответствие второй строки в первой и возвращает мне указатель на первое вхождение, что-то вроде strstr
, но которое не обрабатывает одну и ту же букву, верхнюю или в нижнем регистре, как два разных символа. Для моего примера функция должна найти соответствие для str2
в первой строке, несмотря на верхний регистр "T"
, "Two"
. Надеюсь, я поняла. Заранее спасибо. :)Функция strstr() как, которая игнорирует верхний или нижний регистр
ответ
Из страницы руководства для strstr
:
STRSTR(3) Linux Programmer's Manual STRSTR(3)
NAME
strstr, strcasestr - locate a substring
SYNOPSIS
#include
char *strstr(const char *haystack, const char *needle);
#define _GNU_SOURCE
#include
char *strcasestr(const char *haystack, const char *needle);
DESCRIPTION
The strstr() function finds the first occurrence of the substring needle in
the string haystack. The terminating '\0' characters are not compared.
The strcasestr() function is like strstr(3), but ignores the case of both arguments.
RETURN VALUE
These functions return a pointer to the beginning of the substring, or NULL if
the substring is not found.
Так что вы ищете является strcasestr
.
Моя справочная страница говорит: «Функция strstr() соответствует C89 и C99. Функция strcasestr() является нестандартным расширением». –
Это не в моей библиотеке Visual C. –
Спасибо, это именно то, что я искал. Я не думал об этом в человеке ... В следующий раз я начну с этого. : D – eOf
Реализация stristr()
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char *stristr (const char *str, const char *strSearch) {
char *sors, *subs, *res = NULL;
if ((sors = strdup (str)) != NULL) {
if ((subs = strdup (strSearch)) != NULL) {
res = strstr (strlwr (sors), strlwr (subs));
if (res != NULL)
res = str + (res - sors);
free (subs);
}
free (sors);
}
return res;
}
int main()
{
char *str1 = "One Two Three";
char *str2 = "two";
char *sptr = stristr(str1, str2);
if (sptr)
printf ("Substring is at index %d\n", sptr - str1);
return 0;
}
Несколько «дорогая» реализация. – Clifford
Это полная реализация, +1 для этого. Поскольку он предназначен для системы, которая не все готова, она имеет смысл реализовать ее только с помощью стандартных функций C и не зависит от других функций, которые могут также иметь не такие системы, как 'strdup()' и 'strlwr () '. – chux
Спасибо ... могли написать 'strdup()' и 'strlwr()' too ;-) –
Хотя библиотеки некоторых компилятора C включают расширения с нечувствительны к регистру версий стандартных строковых функций, таких как ГНУ strcasestr()
, именование таких функций не нормируется, даже если оно включено.
Одним из способов преодоления отсутствия стандартной реализации, конечно, реализовать свой собственный:
char* stristr(const char* str1, const char* str2)
{
const char* p1 = str1 ;
const char* p2 = str2 ;
const char* r = *p2 == 0 ? str1 : 0 ;
while(*p1 != 0 && *p2 != 0)
{
if(tolower((unsigned char)*p1) == tolower((unsigned char)*p2))
{
if(r == 0)
{
r = p1 ;
}
p2++ ;
}
else
{
p2 = str2 ;
if(r != 0)
{
p1 = r + 1 ;
}
if(tolower((unsigned char)*p1) == tolower((unsigned char)*p2))
{
r = p1 ;
p2++ ;
}
else
{
r = 0 ;
}
}
p1++ ;
}
return *p2 == 0 ? (char*)r : 0 ;
}
тест ниже код выхода:
Two Three
Two Three
NULL
cdefg
CDEFG
CdEfG
NULL
zzzz
NULL
zzzzz
NULL
int main(void)
{
char* test = stristr("One TTwo Three", "two") ;
printf("%s\n", test == 0 ? "NULL" : test ) ;
test = stristr("One Two Three", "two") ;
printf("%s\n", test == 0 ? "NULL" : test ) ;
test = stristr("One wot Three", "two") ;
printf("%s\n", test == 0 ? "NULL" : test ) ;
test = stristr("abcdefg", "cde") ;
printf("%s\n", test == 0 ? "NULL" : test ) ;
test = stristr("ABCDEFG", "cde") ;
printf("%s\n", test == 0 ? "NULL" : test ) ;
test = stristr("AbCdEfG", "cde") ;
printf("%s\n", test == 0 ? "NULL" : test ) ;
test = stristr("1234567", "cde") ;
printf("%s\n", test == 0 ? "NULL" : test ) ;
test = stristr("zzzz", "zz") ;
printf("%s\n", test == 0 ? "NULL" : test ) ;
test = stristr("zz", "zzzzz") ;
printf("%s\n", test == 0 ? "NULL" : test ) ;
test = stristr("", "") ;
printf("%s\n", test == 0 ? "NULL" : test ) ;
test = stristr("zzzzz", "") ;
printf("%s\n", test == 0 ? "NULL" : test ) ;
test = stristr("", "zzzz") ;
printf("%s\n", test == 0 ? "NULL" : test ) ;
test = stristr("AAABCDX","AABC") ;
printf("%s\n", test == 0 ? "NULL" : test ) ;
return 0;
}
@chux: Хорошее место - работает, чтобы исправить. – Clifford
Я тоже попал в угловые случаи, пытаясь действовать как 'strstr (" "," zz "), strstr (" zz "," "), strstr (" "," ")'. – chux
Исправленные '' "," "и' "zzzz", "" 'test cases - возвращают' str1' согласно стандарту 'strstr()'. – Clifford
После принимать ответ
Вдохновленный @Clifford и @Weather Vane, подумал, что я попробую свернуть решение, которое использовало бы только стандартные библиотечные функции.
char* stristr3(const char* haystack, const char* needle) {
do {
const char* h = haystack;
const char* n = needle;
while (tolower((unsigned char) *h) == tolower((unsigned char) *n) && *n) {
h++;
n++;
}
if (*n == 0) {
return (char *) haystack;
}
} while (*haystack++);
return 0;
}
Несколько сложнее, чтобы соответствовать углу случаи strstr()
с входами, как "x",""
, "","x"
, "",""
Nice - я исправил мой, чтобы произвести тот же результат, что и ваш. Возможно, вы несколько более лаконичны. Броски не нужны ('tolower()' принимает 'int' - передача символа является безопасным и нормальным), а подпись strstr() в C - это' char * strstr (char *, const char *) ', поэтому приведение в обратном направлении не требуется, если вы используете это. – Clifford
@Clifford C11 7.4 Обработка символов говорит, что «аргумент является« int », значение которого должно быть представлено как« unsigned char »или должно быть равно значению макроса« EOF ». Если аргумент имеет любое другое значение, поведение не определено »Итак, если' char' подписан и 'ch <0', то передача его в' tolower (ch) 'приводит к тому, что' ch' остается отрицательным числом и не попадает в диапазон 'unsigned char' - таким образом, UB. При первом литье '(unsigned char) ch', код заставляет неотрицательное значение передается' tolower() '. – chux
Я задавался вопросом о необходимости неподписанного символа, поскольку буквы находятся ниже значения ASCII 128. Затем я попробовал его с «Über» и «über», и это все равно не работает, потому что, в отличие от английского верхнего/нижнего регистра, значения 129 и 154 ASCII не разделены на 32. –
Лучший способ решить эту проблему без написания функции может быть сначала преобразовать как строку в нижний регистр/верхний регистр с помощью «TOLOWER»/«ToUpper», а затем использовать «strstr» :)
Но лучше всего перевести верхний/нижний регистр в функции - так что вы будете писать функцию. Что случилось с написанием функции в любом случае? – Clifford
да .. Я говорил о стандартной библиотеке, поскольку она уже оптимизирована. –
Преобразование строк - лишние накладные расходы - сначала их нужно дублировать, поэтому оптимизация библиотеки становится неактуальной. Ваше предложение - это именно то решение, которое предлагает Weather Vane, и я сделал некоторый анализ производительности на этом и добавил результаты в комментарии. В любом случае это не простой однострочный, так что вам все равно будет лучше писать функцию, как в ответе Weather Vane. Библиотека строк C (и любые расширения) действительно может быть оптимизирована, но обработка строк C в корне неэффективна, а 'strdup()' особенно дорого. – Clifford
Вот немного более эффективная версия, которая не вызывает tolower()
дважды на символ в строке haystack
:
#include <ctype.h>
char *stristr4(const char *haystack, const char *needle) {
int c = tolower((unsigned char)*needle);
if (c == '\0')
return (char *)haystack;
for (; *haystack; haystack++) {
if (tolower((unsigned char)*haystack) == c) {
for (size_t i = 0;;) {
if (needle[++i] == '\0')
return (char *)haystack;
if (tolower((unsigned char)haystack[i]) != tolower((unsigned char)needle[i]))
break;
}
}
}
return NULL;
}
O() для этого и [that] (https://stackoverflow.com/a/27305359/2410359) являются как «O (h_len * n_len)». Поистине более эффективным будет использование «O (h_len + n_len) подход. – chux
@chux: Я согласен, и я написал * немного более эффективно *. Альтернативные версии с ** O (h_len + n_len) ** имеют стоимость установки, которая в большинстве случаев делает ее более медленной. ** O (h_len * n_len) ** - худший случай, происходящий только для строк патологических аргументов. – chqrlie
Мои тесты показывают, что это значительно быстрее (и такая же функциональность). – chux
Если вы находитесь в окнах, вы можете использовать StrStrI. Он работает так же, как и GNU strcasestr
, или другой вручную реализованный код stristr
в других ответах здесь.
т.д .:
const char needle[] = "and";
const char haystack[] = "me and you";
const char* pAnd = StrStrIA(haystack, needle); // explicitly call ascii version as windows defaults to wchar
printf("%s\n", pAnd); // Prints "and you";
есть ya go! занял так много времени, чтобы найти это ?! –
- 1. System.Windows.Forms.Keys - нижний или верхний регистр?
- 2. Sublime 3 верхний/нижний регистр ярлык/функция
- 3. Верхний и нижний регистр
- 4. Имена методов HTTP: верхний или нижний регистр?
- 5. PHP верхний регистр равно нижний регистр
- 6. Зарегистрированный пользователь проверяет нижний регистр или верхний регистр
- 7. преобразование атома в верхний регистр (или нижний регистр) [SICStus]
- 8. PHP array_ сливаться array_unique нижний/верхний регистр
- 9. Как сделать Class.forName игнорировать нижний регистр/верхний регистр
- 10. regex string substitution верхний и нижний регистр
- 11. Верхний или нижний регистр для всех турецких символов в DB2
- 12. Как обрабатывать верхний или нижний регистр в JSR 310?
- 13. Рандомизируйте верхний или нижний регистр на всех строковых символах
- 14. Как изменить верхний регистр на нижний регистр в строке?
- 15. как преобразовать нижний регистр символов в верхний регистр?
- 16. как преобразовать верхний регистр в нижний регистр в ckeditor?
- 17. Нижний регистр windows.h и верхний регистр Windows.h разница?
- 18. Преобразование строки в верхний и нижний регистр
- 19. Продвинутый чековый регистр (верхний/нижний) в строке
- 20. JavaScript - querySelectorВсе и нижний/верхний регистр
- 21. значения проверки JQuery верхний и нижний регистр
- 22. Unix, верхний корпус в нижний регистр
- 23. регулярное выражение и верхний и нижний регистр
- 24. Сортировка Rails Верхний и нижний регистр
- 25. Преобразование строки в порядковый верхний или нижний регистр
- 26. Преобразование конкретных букв в верхний или нижний регистр в python
- 27. Верхний или нижний регистр определенного символа в слове «Java»
- 28. Umbraco 7: Изменить URL-адрес на верхний или нижний регистр
- 29. Редактор Atom: RegEx заменяет на верхний или нижний регистр
- 30. Python заменить строку (верхний или нижний регистр) другой строкой
Почему вы не просто преобразовать их обоих в нижний/верхний регистр, а затем сравнить их? –
Какой код у вас есть? Какой язык программирования вы используете? – danfuzz
Нет библиотеки 'stristr()' C, но вы можете сделать ее для себя ... –