Есть много условий, вы должны проверить, чтобы обеспечить для вас только соответствующие целые слова и т.д. Ниже один подход к поиску jury
и только соответствие jury
, jury's
, но не injury
. Вы должны также рассмотреть вопрос о том, хотите ли вы сопоставлять множественные числа для слова или нет (например, review
и reviews
. Под одной коллекцией разделителей (delim
) считается обеспечение соответствия целых слов. Вы можете легко разбить это на два и иметь начало и конечный набор, если вы хотите совместить множественные числа или различные другие суффиксы.
Код ожидает, что имя файла будет искать в качестве первого аргумента и поискового запроса (sterm
) как второе. (если аргументы не указаны, он будет искать текст на stdin
для 'the'
). Код читает каждую строку в файле во временном буфере, называемом line
, а затем ищет каждый символ в line
для начального символа в sterm
. Если найден, предыдущий символ проверяется, чтобы гарантировать, что это разделитель, а затем символ, следующий за словом (на sterm
), также является разделителем. Если это слово, начинающееся с того же символа, что и sterm
, делится до и после, то содержимое сравнивается с использованием strncmp
.
Если все условия выполнены, слово копируется в tmp
, а count
- приращение. Результаты печатаются вместе с нулевым основанием в позиции line
для матча. Это всего лишь основной поиск целых слов, который не был оптимизирован, но должен дать вам начальное место для различения целых слов из менее содержащихся подстрок. (т. е. поиск 'the'
также не соответствует 'them'
, 'then'
, 'they'
и т. д.). Вы также можете превратить этот код в функцию, которая сохраняет номер строки и позицию каждого совпадения в массиве структур, на которые вы можете вернуть указатель. Таким образом, вы можете анализировать текст и возвращать указатель на массив, который содержит строку и позицию каждого совпадения. (это на другой день).
Просмотрите этот код и сообщите, если у вас есть вопросы. Если вы не касаетесь только соответствия целых слов, тогда вы можете просто позвонить strstr
несколько раз в каждой строке, продвигая указатель, чтобы посчитать появление условия поиска. Что бы ни было лучше всего соответствует вашим потребностям.
#include <stdio.h>
#include <string.h>
#define MAXS 256
int main (int argc, char **argv)
{
char line[MAXS] = {0}; /* line buffer for fgets */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
char *sterm = argc > 2 ? argv[2] : "the";
char *delim = " \t\n\'\".";
size_t count = 0, idx = 0, slen = strlen (sterm);
if (!fp) {
fprintf (stderr, "error: file open failed '%s'\n", argv[1]);
return 1;
}
while (fgets (line, MAXS, fp))
{
size_t i, llen = strlen (line);
idx++;
if (llen < slen + 1)
continue; /* line not longer than search term + \n */
for (i = 0; i < llen - slen + 1; i++) {
if (line[i] != *sterm)
continue; /* char != first char in sterm */
if (i && !strchr (delim, line[i-1]))
continue; /* prior char is not a delim */
if (!strchr (delim, line[i+slen]))
continue; /* next char is not a delim */
if (strncmp (&line[i], sterm, slen))
continue; /* chars don't match sterm */
printf (" line[%2zu] match %2zu. '%s' at location %zu\n",
idx, ++count, sterm, &line[i] - line);
}
}
if (fp != stdin) fclose (fp);
printf ("\n total occurrences of '%s' in '%s' : %zu\n\n",
sterm, argc > 1 ? argv[1] : "stdin", count);
return 0;
}
Пример файла
$ cat dat/damages.txt
Personal injury damage awards are unliquidated
and are not capable of certain measurement; thus, the
jury has broad discretion in assessing the amount of
damages in a personal injury case. Yet, at the same
time, a factual sufficiency review insures that the
evidence supports the jury's award; and, although
difficult, the law requires appellate courts to conduct
factual sufficiency reviews on damage awards in
personal injury cases. Thus, while a jury has latitude in
assessing intangible damages in personal injury cases,
a jury's damage award does not escape the scrutiny of
appellate review.
Because Texas law applies no physical manifestation
rule to restrict wrongful death recoveries, a
trial court in a death case is prudent when it chooses
to submit the issues of mental anguish and loss of
society and companionship. While there is a
presumption of mental anguish for the wrongful death
beneficiary, the Texas Supreme Court has not indicated
that reviewing courts should presume that the mental
anguish is sufficient to support a large award. Testimony
that proves the beneficiary suffered severe mental
anguish or severe grief should be a significant and
sometimes determining factor in a factual sufficiency
analysis of large non-pecuniary damage awards.
Выход
$ ./bin/searchterm dat/damages.txt jury
line[ 3] match 1. 'jury' at location 0
line[ 6] match 2. 'jury' at location 22
line[ 9] match 3. 'jury' at location 37
line[11] match 4. 'jury' at location 2
total occurrences of 'jury' in 'dat/damages.txt' : 4
или
$ ./bin/searchterm <dat/damages.txt
line[ 2] match 1. 'the' at location 50
line[ 3] match 2. 'the' at location 39
line[ 4] match 3. 'the' at location 43
line[ 5] match 4. 'the' at location 48
line[ 6] match 5. 'the' at location 18
line[ 7] match 6. 'the' at location 11
line[11] match 7. 'the' at location 38
line[17] match 8. 'the' at location 10
line[19] match 9. 'the' at location 34
line[20] match 10. 'the' at location 13
line[21] match 11. 'the' at location 42
line[23] match 12. 'the' at location 12
total occurrences of 'the' in 'stdin' : 12
Использование указателя вместо индекса массива нотации
Вы можете найти его немного более естественно использовать указатель вместо индекс массива обозначения. (например, используя char *p = line;
и продвигаясь p
, вместо использования line[X]
обозначение). Если да, то вы можете заменить читать петлю следующим образом:
while (fgets (line, MAXS, fp))
{
char *p = line;
size_t llen = strlen (line);
idx++;
if (llen < slen + 1)
continue; /* line not longer than search term + \n */
for (;p < (line + llen - slen + 1); p++) {
if (*p != *sterm)
continue; /* char != first char in sterm */
if (p > line && !strchr (delim, *(p - 1)))
continue; /* prior char is not a delim */
if (!strchr (delim, *(p + slen)))
continue; /* next char is not a delim */
if (strncmp (p, sterm, slen))
continue; /* chars don't match sterm */
printf (" line[%2zu] match %2zu. '%s' at location %zu\n",
idx, ++count, sterm, p - line);
}
}
Указатель обозначений, вероятно, немного более естественно C. Дайте мне знать, если у вас есть какие-либо вопросы.
Привет, я попытался сохранить файл в строке. но это не работает. – holger94
, затем я попробовал «fscan» и «fgets». :/ – holger94
где переменная «текст» определена? – Pooya