Не совсем понятно из вашего использования «неперекрывающихся», каково ваше намерение с data
, но я беру это из ваших дополнительных комментариев, которые вы хотите найти "on"
в data
как целое словоа не "on"
как часть "Jason"
.
При попытке найти "on"
в пределах data
вам не нужен strtok, strspn
или strcspn
, правильный инструмент для работыравен strstr
, что позволяет найти первое вхождение подстроки в строке.Ваша единственная работа заключается в определении правильной подстроки для поиска.
Поскольку в этом случае вы хотите штрафовать "on"
как целое слово, почему бы не найти " on"
, чтобы найти "on"
, которому предшествуетпространство.(Вы могли бы также расширить это на все пробелы, но для целей вашего предложения мы будем использовать слова, разделенные пробелом, а затем расширим проверку для всех пробелов, чтобы убедиться, что следующее "on"
- это пробел).
Во-первых,связанных с вашей инициализацией data
, если вы не собираетесь добавлять свою строку в свой код, нет необходимости указывать magic-number 50
, просто оставьте []
пустым и data
будет иметь соответствующий размер для хранения строки, например,
char data[]="Jason could you please turn on the TV",
*p = data; /* pointer to data */
Аналогично, если вы не планируете изменить свой разделитель, вы можете просто использовать string-literal , например
const char *delim = " on";
Затем, чтобы найти " on"
в данных, все, что вам нужно, это один вызов strstr (p, delim)
, и вы можете сделать вызов в условном выражении, чтобы определить, существует ли он, например,
if ((p = strstr (p, delim))) {
size_t len = strlen (delim);
char *next = p + len;
if (isspace (*next) || ispunct (*next)) {
printf ("found: '%s' (now what?)\n", ++p);
}
}
Если он найден, просто объявите указатель (или используйте индексирование массива с помощью p
), чтобы получить доступ к следующему символу после " on"
.Затем вы можете проверить, является ли то, что следует " on"
, пробелом, который подтверждает, что вы нашли нужную подстроку.Поскольку вы знаете, p
указывает на space
до "on"
, вы можете просто увеличить указатель p
, чтобы он указывал на "on"
, как это было сделано выше в инструкции printf
.Теперь то, что вы делаете с остальной частью строки, зависит от вас.У вас есть p
, указывающий на начало строки, и next
, указывающий на пробел после "on"
, так что вы можете тривиально скопировать "on"
или nul-terminate в next
-все, что вам нужно сделать.
Если сложить все вместе, вы получите:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main (void) {
char data[]="Jason could you please turn on the TV",
*p = data;
const char *delim = " on";
if ((p = strstr (p, delim))) {
size_t len = strlen (delim);
char *next = p + len;
if (isspace (*next) || ispunct (*next)) {
printf ("found: '%s' (now what?)\n", ++p);
}
}
return 0;
}
Пример использования / Вывод
$ ./bin/strstr_on
found: 'on the TV' (now what?)
Взглядвсе кончено, и дайте мне знать, если у вас есть какие-либо дополнительные вопросы.
Поиск нескольких "on"
В строке
Как объяснено в комментариях ниже, если у вас есть несколько "on"
находится на вашем входе, все, что вам нужно сделать, это поместить приведенный выше оператор if
в цикл, а затем установить p = next;
в конце цикла.Например, единственные изменения, необходимые для поиска всех подстрок, начинающихся с "on"
, можно сделать следующим образом:
char data[]="Jason could you please turn on the TV on the desk",
...
while ((p = strstr (p, delim))) {
size_t len = strlen (delim);
char *next = p + len;
if (isspace (*next) || ispunct (*next)) {
printf ("found: '%s' (now what?)\n", ++p);
}
p = next;
}
Использовать / выводить Поиск всех "on"
$ ./bin/strstr_on
found: 'on the TV on the desk' (now what?)
found: 'on the desk' (now what?)
Дайте мне знать, если у вас есть еще вопросы.