Почему происходит exited, segmentation fault
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
char **words=NULL; // указатель на слова
int num_words=0; // кол во слов
char *delim=" \t\n,.!?:";
int size_file=0; //размер файла
FILE *fp=fopen("test.txt", "r");
fseek(fp, 0, SEEK_END);
size_file=ftell(fp); //находим размер файла
printf("%d\n", size_file);
char *buffer=calloc(size_file+1, sizeof(char*)); //буфер
if(buffer==NULL) {
printf("Ошибка выделения памяти\n");
exit(-1);
}
fseek(fp, 0, SEEK_SET);
fread(buffer, 1, size_file, fp);
printf("\nТекст файла\n\n");
printf("%s\n", buffer);
char *istr=strtok(buffer, delim);
while(istr) {
words=realloc(words, (num_words+1)*sizeof(char*));
words[num_words++]=istr;
istr=strtok(NULL, delim);
//printf("%s\n", istr);
}
/*for (int i=0; i<num_words;i++) {
printf("%p\n", words[i]);
}*/
printf("Количество символов в файле :%d\n", size_file);
printf("Количество слов в файле :%d\n\n", num_words);
for (int i=0; i<num_words; i++) {
puts(words[i]);
}
printf("\nНахождение одинаковых слов\n");
for (int i=0; i<num_words;i++) {
for (int j=0; i<num_words;j++) {
if (strcmp(words[i],words[j])==0) {
//тут пытаюсь реализовать счетчик сколько раз повторялось слово, пока не выходит.
}
}
}
fclose(fp);
return 0;
}
И как можно реализовать подсчет повторений каждого слова(например "the"=3, то есть встретилось в тексте 3 раза и т д)
Ответы (2 шт):
У вас в последнем цикле опечатка.
printf("Количество символов в файле :%d\n", size_file);
printf("Количество слов в файле :%d\n\n", num_words);
for (int i=0; i<num_words; i++) {
puts(words[i]);
}
int *cnt = (int*) malloc(num_words*sizeof(int));//массив повторений
printf("\nНахождение одинаковых слов\n");
for (int i=0; i<num_words;i++) {
cnt[i] = 0;
for(int j=0; /*ошибка в виде 'i'*/ j<num_words;j++)
if (strcmp(words[i],words[j])==0) cnt[i]++;
}
fclose(fp);
//вывод нужного кол-ва элементов одинаковых элементов (т.е. в данном случае первых cnt[0])
printf("\n%d",cnt[0]);
return 0;
}
И как можно реализовать подсчет повторений каждого слова(например "the"=3, то есть встретилось в тексте 3 раза и т д)
Например, (сильно не меняя идею, которую вы пыталиcь реализовать во вложенных циклах) так:
int *wcnt = calloc(num_words, sizeof(int));
char *is_first = calloc(num_words, sizeof(char));
printf("\nНахождение одинаковых слов\n");
for (int i=0; i<num_words;i++) {
wcnt[i]++;
for (int j=0; j<num_words;j++) {
if (i != j && strcmp(words[i],words[j])==0) {
//тут пытаюсь реализовать счетчик сколько раз повторялось слово, пока не выходит.
if (wcnt[i]++ == 1 && i < j)
is_first[i] = 1;
}
}
}
for (int i=0; i<num_words; i++) {
if (wcnt[i] == 1 || is_first[i])
printf("%s\t %d\n", words[i], wcnt[i]);
}
Более эффективно можно решить ту же задачу, используя сортировку (одинаковые слова окажутся рядом) или map (хэш-таблицу), хранящую в качестве ключа слово, а в качестве данных счетчик.
Конечно,, более эффективно реализовать is_first[] как битовый вектор (займет в 8 раз меньше памяти), но не захотел загружать вас еще и операциями с битами.