Hello. It was necessary to find the word entered from the keyboard in the file and display its position (positions - if several are found). I wrote this function, however, as if I did not try to avoid it, but in places where dots and spaces go in a row, the word counter is lost. Please help.

void search (FILE* file, char t[20], char *x, unsigned size) { unsigned a=0, k=0, max=0, i=0, j=0; while ((x[i]=fgetc(file)) != EOF) ++i; max=strlen(t); for (i=0; i<(size-1); ++i) { if (((x[i+1]==' ') || (x[i+1]=='.') || (x[i+1]=='\n') || (x[i+1]==EOF)) && (i != (size-2)) && ( (x[i+2] != ' ') || (x[i+2] != EOF) || (x[i+2] != '.') || (x[i+2] != ',') )) ++j; if (t[k]==x[i]) { ++k; if ((k==max) && ((x[i-max]==' ') || (x[i-max])==',' || (x[i-max]=='.')) && ((x[i+1]==' ') || (x[i+1]=='.') || (x[i+1]==EOF) || (x[i+1]=='\n')) && ((x[i+2] != ' ') || (x[i+2] != EOF) || (x[i+2] != '.') || (x[i+2] != ','))) { printf("%d ", j); ++a; } } } if (a==0) printf("Not found."); printf("\n"); } 

2 answers 2

To walk so to walk :) But first, the fgetc() prototype is:

 int fgetc(FILE *stream); 

Reading from a file in char is a gross error.

 #include <string.h> #include <stdio.h> /* * Возвращает количество вхождений слова word в файл. * Заполняет массив pos[] позициями слов в файле (не больше max раз). * Или под позицией имеется в виду порядковый номер слова? Да пофиг, * переделать не проблема, код даже проще станет. * Символы-разделители слов задаются аргументом delim. */ static size_t find_word(FILE * file, const char * delim, const char * word, long * pos, size_t max) { size_t words = 0; size_t wlen = strlen(word); long cpos = 1; while (words < max) { pos[words++] = 0xDEADBEEF; } words = 0; int c = fgetc(file); while (c != EOF && words < max) { if (strchr(delim, c)) { /* разделитель слов, пропускаем */ c = fgetc(file); cpos++; continue; } /* не разделитель, проверяем на совпадение с первой буквой слова */ else if (c == *word) { /* OK, читаем символы дальше и сравниваем со словом */ size_t i = 1; while (i < wlen) { c = fgetc(file); cpos++; if (c == EOF) { /* конец фильма, выходим */ return words; } if (c != word[i]) { break; } i++; } if (i == wlen) { /* * совпали wlen символов, надо проверить следующий * (если он не разделитель, то не считаем слово) */ c = fgetc(file); cpos++; if (c == EOF) { /* конец фильма, слово найдено */ pos[words] = cpos; words++; return words; } if (strchr(delim, c)) { pos[words] = cpos; words++; } continue; } } c = fgetc(file); cpos++; } return words; } /* * Проверяем: */ int main() { const char delim[] = " .,;'!?'\"[]{}()\r\n\t"; const char word[] = "word"; const char file[] = "file.txt"; /* Ну... Лонг так лонг, не будем упираться... */ long pos[16]; FILE * f = fopen(file, "r"); if (!f) { perror(file); return -1; } printf("Word count: %zu\n", find_word(f, delim, word, pos, sizeof(pos) / sizeof(pos[0]))); fclose(f); return 0; } 
  • I will chew on all this now. Thank you very much for your efforts. But for starters: what is the type at the end of %zu ? - Halva
  • This is the format for size_t . - PinkTux
  • Climbs unknown conversion type character 'z' in format to it. - Halva
  • What compiler? If you do not understand, you can replace it with %u . - PinkTux

I corrected my decision. Here's what happened:

 #include <stdio.h> #include <malloc.h> #include <stdlib.h> #include <string.h> unsigned maxlength (FILE* file, char *x); void correction (char *x, unsigned size, unsigned max); void search (FILE* file, char t[20], char *x, unsigned size); void searchwo(FILE* file, char t[20], char *x, unsigned size); int main() { FILE *myfile; char *text, word[20]; unsigned k, size, max, i, j; while (k != 3) { printf("Please, select action: \n 1) Correction \n 2) Search \n 3) Exit \n"); scanf("%d", &k); switch (k) { case 1: myfile = fopen ("input.txt", "r"); fseek(myfile, 0, SEEK_END); size = ftell(myfile); rewind(myfile); text=(char*) malloc(size); max=maxlength(myfile, text); fclose(myfile); myfile = fopen ("output.txt", "w"); correction(text, size, max); for (i=0; i<size; ++i) fputc(text[i], myfile); fclose(myfile); free(text); break; case 2: myfile = fopen ("output.txt", "r"); fseek(myfile, 0, SEEK_END); size = ftell(myfile); rewind(myfile); text=(char*) malloc(size); printf("Enter a word... \n"); scanf("%s", word); printf("1) With register \n2) W\\o register \n"); scanf("%d", &j); switch (j) { case 1: search(myfile, word, text, size); break; case 2: searchwo(myfile, word, text, size); } free(text); fclose(myfile); break; default: printf("Press any key... \n"); } } return 0; } unsigned maxlength (FILE* file, char *x) { unsigned i=0, k=0, max=0; while ((x[i] = fgetc(file)) != EOF) { if ((x[i] != ' ') && (x[i] != '\n')) ++k; else k=0; if (k>max) max=k; ++i; } return max; } void correction (char *x, unsigned size, unsigned max) { unsigned k=0, i=0; if ((x[i]<123) && (x[i]>96)) printf("%c", x[0]=x[0]-32); else printf("%c", x[0]); for (i=1; i<size; ++i) { ++k; if (x[i-4]!='.' && x[i-2]=='.' && ((x[i-1]==' ') || (x[i-1]=='\n')) && (x[i]<123) && (x[i]>96)) printf("%c", x[i]=x[i]-32); else if ((x[i]==' ') && (k>(120-max))) { printf("\n"); k=0; } else printf("%c", x[i]); } printf("\n"); } void search (FILE* file, char t[20], char *x, unsigned size) { unsigned a=0, k=0, max=0, i=0, j=0; max=strlen(t); printf("dlina = %d \n", max); for (i=0; i<size; ++i) x[i]=fgetc(file); for (i=0; i<size; ++i){ if (((x[i] != ' ') && (x[i] != ',') && (x[i] != '.') && (x[i] != '\n') && (x[i] != EOF)) && ((x[i+1]==' ') || (x[i+1]=='.') || (x[i+1]=='\n') || (x[i+1]==EOF) || (x[i+1]==','))) { ++j; } if (t[k]==x[i]) ++k; if (k==max && ((i-max)==-1 || x[i-max]==' ') && (x[i+1]==',' || x[i+1]==' ' || x[i+1]=='.')) { printf("%d ", j); ++a; k=0; } if (((x[i] != ' ') && (x[i] != ',') && (x[i] != '.') && (x[i] != '\n') && (x[i] != EOF)) && ((x[i+1]==' ') || (x[i+1]=='.') || (x[i+1]=='\n') || (x[i+1]==EOF) || (x[i+1]==','))) k=0; } if (a==0) printf("Not found"); printf("\n"); } void searchwo(FILE* file, char t[20], char *x, unsigned size) { unsigned a=0, k=0, max=0, i=0, j=0; max=strlen(t); printf("dlina = %d \n", max); for (i=0; i<size; ++i) x[i]=fgetc(file); for (i=0; i<size; ++i){ if (((x[i] != ' ') && (x[i] != ',') && (x[i] != '.') && (x[i] != '\n') && (x[i] != EOF)) && ((x[i+1]==' ') || (x[i+1]=='.') || (x[i+1]=='\n') || (x[i+1]==EOF) || (x[i+1]==','))) { ++j; } if (t[k]==x[i] || t[k]==x[i]-32 || t[k]==x[i]+32) ++k; if (k==max && ((i-max)==-1 || x[i-max]==' ') && (x[i+1]==',' || x[i+1]==' ' || x[i+1]=='.')) { printf("%d ", j); ++a; k=0; } if (((x[i] != ' ') && (x[i] != ',') && (x[i] != '.') && (x[i] != '\n') && (x[i] != EOF)) && ((x[i+1]==' ') || (x[i+1]=='.') || (x[i+1]=='\n') || (x[i+1]==EOF) || (x[i+1]==','))) k=0; } if (a==0) printf("Not found"); printf("\n"); } 
  • publishing the entire code (related and non-question related) without explanation is not a good answer. Tell me in words what was the problem of the code in question and how exactly your code solved it. - jfs