2016-01-20 7 views
0

Надеюсь, кто-то может мне помочь. Я думаю, что это простой вопрос, Я хочу написать программу, которая ищет слова в файле.C поиск слов в строке

char *such = "Ingo"; 
char *fund; 
FILE *datei; 
char text[100]; 

datei = fopen("names.txt", "r"); 

if (datei == NULL) { 
    printf("Fehler\n"); 
} 
else 
{ 
    fscanf(datei, "%100c", text); 
    text[100] = '\0'; 
    //i think this dont work 
    if (fgets(text, 100, datei) != NULL) 
    { 
     printf("%s \n", text); 
    } 
} 

return 0; 

Файл содержит это:

Ingo Test Test 123 Test Ingo Ingo 

Теперь я хочу, чтобы искать, как часто название «Инго» находится в файле.

Можно найти больше слов, может быть, «ingo» и «test» и считать это?

+0

Привет, я попытался сохранить файл в строке. но это не работает. – holger94

+0

, затем я попробовал «fscan» и «fgets». :/ – holger94

+0

где переменная «текст» определена? – Pooya

ответ

1

Есть два очень простых способов сделать это:

  1. В цикле вы используете fscanf, чтобы найти слова из файла, пока не дойдете до EOF, и в то же время попросишь ли это слово то, что вы ищете с strcmp (string compare) from string.h

  2. Используйте две петли во внешнем цикле с fgetc, чтобы получить символы, пока не достигнете какого-либо разделителя, такого как пробел или \ n или \ t, и во внутреннем цикле проверьте, сканирование с помощью getc - это слово, которое вы ищете. Для этого вам понадобится временный массив символов.

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

int main(void) { 
    char *such = "Ingo"; 
    FILE *datei; 
    char word[100]; 
    int counter = 0; 

    datei = fopen("names.txt", "r"); 

    if (datei == NULL) { 
     printf("Fehler\n"); 
    } 
    else 
    { 
     while(1==fscanf(datei, "%99s", word)){//read word by word 
      word[0] = toupper(word[0]);  //ingo --> Ingo 
      if (strcmp(word, such) == 0){ 
       ++counter; 
      } 
     } 
     fclose(datei); 
     if (counter != 0){ 
      printf("number of '%s' is %d\n", such, counter); 
     } 

    } 

    return 0; 
} 
1

Есть много условий, вы должны проверить, чтобы обеспечить для вас только соответствующие целые слова и т.д. Ниже один подход к поиску 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. Дайте мне знать, если у вас есть какие-либо вопросы.

Смежные вопросы