2014-12-06 3 views
2

Предположим, у меня есть следующая строка:Match точная строка с strstr

in the interior of the inside is an inner inn 

и я хочу искать, скажем, для вхождений «в» (как часто «в» появляется).

В моей программе я использовал strstr, чтобы сделать это, но он возвращает ложных срабатываний. Он вернет:

- in the interior of the inside is an inner inn 
- interior of the inside is an inner inn 
- inside is an inner inn 
- inner inn 
- inn 

Таким образом, мышление «в» появляется 5 раз, что, очевидно, не так.

Как следует искать исключительно за слово "in"?

+1

Вы хотите сказать, что есть только один «в»? –

+0

В этом случае да, есть только одно слово «in». Но для строки: «внутри внутри внутри находится», есть 3. – Alex

ответ

2

Попробуйте следующее

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

int main(void) 
{ 
    char *s = "in the interior of the inside is an inner inn"; 
    char *t = "in"; 
    size_t n = strlen(t); 

    size_t count = 0; 
    char *p = s; 

    while ((p = strstr(p, t)) != NULL) 
    { 
     char *q = p + n; 
     if (p == s || isblank((unsigned char) *(p - 1))) 
     { 
      if (*q == '\0' || isblank((unsigned char) *q)) ++count; 
     } 
     p = q; 
    } 

    printf("There are %zu string \"%s\"\n", count, t); 

    return 0; 
} 

Выход является

There are 1 string "in" 

Вы также можете добавить проверку на ispunct, если источник строка может содержать puctuations.

+0

Я вижу, что мой ответ достаточно логичен для вашей логики. +1 к этому более раннему ответу. – chux

+0

@chux Прямолинейные подходы выглядят одинаково. –

2

Поиск "in"; обратите внимание на пробелы. Затем рассмотрим краевые случаи предложения, начиная с «in» и заканчивая «in».

+0

Что делать, если слова разделены запятыми, точками, восклицательными знаками и т. Д.? – Alex

+0

Ну, как я бы сказал, это изменение спецификации! Это будет сделано для начинающих. В действительности, используйте библиотеку регулярных выражений. – Bathsheba

2

Еще один способ сделать это:

Использования strtok() на всем ваше предложение с пространством в качестве разделителя.

Итак, теперь вы можете проверить свой маркер против «в»

+0

Будет ли это работать для «xxin»? 'strtok()' отлично работает для трейлинг-разделителя, но не так хорошо для ведущего разделителя. – chux

+0

'strtok()' приведет к неопределенному поведению, если он пережевывает строку только для чтения, такую ​​как 'const char * foo =" я в беде "' – Bathsheba

+0

@chux Для данного предложения это будет работать и я имел в виду, если вы хотите для проверки «в» в вашем предложении тогда это будет работать – Gopi

1

Добавить isdelimiter() для проверки до и после результата strstr().

// Adjust as needed. 
int isdelimiter(char ch) { 
    return (ch == ' ') || (ch == '\0'); 
} 

int MatchAlex(const char *haystack, const char *needle) { 
    int match = 0; 
    const char *h = haystack; 
    const char *m; 
    size_t len = strlen(needle); 
    while ((m = strstr(h, needle)) != NULL) { 
    if ((m == haystack || isdelimiter(m[-1])) && isdelimiter(m[len])) { 
     // printf("'%s'",m); 
     match++; 
     h += len; 
    } else { 
     h++; 
    } 
    } 
    return match; 
} 

int main(void) { 
    printf("%d\n", 
     MatchAlex("in the interior of the inside is an inner inn xxin", "in")); 
    return 0; 
} 
Смежные вопросы