Задать вопрос
@Treeesk

Какая ошибка в коде на С?

Доброго времени суток!Не могу найти ошибку в коде. Задание: Напишите программу печати таблицы "перекрестных ссылок", которая будет печатать все слова документа и указывать для каждого из них номера строк, где оно встретилось. Программа должна игнорировать "шумовые" слова, такие как "и", "или" и пр. Я хочу чтобы у каждого слова выводился рядом массив с номерами строк в которых это слово встречается, но у меня выводятся только 1 и на этом все. При вводе:
hello abfdbdbdf
hello
Я хочу увидеть:
hello 1 2
abfdbdbdf 1

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

#define C_OF_STR 100

struct tnode {
    char *word;
    int num_str[C_OF_STR];
    struct tnode *left;
    struct tnode *right;
    int last_el;
};

/* talloc: создает tnode */
struct tnode *talloc(void) {
    return (struct tnode *) malloc(sizeof(struct tnode));
}

char *strdup_(char *s) /* делает дубликат s */
{
    char *p;
    p = (char *) malloc(strlen(s)+1); /* +1 для '\0' */
    if (p != NULL)
        strcpy(p, s);
    return p;
}

/* addtree: добавляет слово в дерево */
struct tnode *addtree(struct tnode *p, char *word, int ind) {
    int cond;
    if (p == NULL) {
        p = talloc();
        p->word = strdup_(word);
        p->last_el = 0;
        p->num_str[p->last_el++] = ind;
        p->left = p->right = NULL;
    }
    else if ((cond = strcmp(word, p->word)) == 0) {
        // Если слово уже есть, добавляем индекс в массив
        if (ind != p->num_str[p->last_el - 1]) {
            if (p->last_el < C_OF_STR) {
                p->num_str[p->last_el++] = ind;
            }
            else {
                printf("A lot of strings");
                exit(1);
            }
        }
    }
    else if (cond < 0) {
        p->left = addtree(p->left, word, ind);
    }
    else {
        p->right = addtree(p->right, word, ind);
    }
    return p;
}

#define BUFSIZE 100
char buf[BUFSIZE]; // Буфер для ungetch
int bufp = 0; // След. свободная позиция в буфере

int getch(void) { // Взять символ из ввода
    return (bufp > 0) ? buf[--bufp] : getchar();
}

void ungetch(int c) { // Вернуть символ на ввод
    if (bufp >= BUFSIZE)
        printf("ungetch: a lot of symbols\n");
    else
        buf[bufp++] = c;
}

/* getword: принимает следующее слово или символ из ввода */
int getword(char *word, int lim) {
    char c;
    char *w = word;
    while (isspace(c = getch())); // Пропуск пробелов
    if (c == EOF) {
        *w = '\0';
        return EOF;
    }
    if (!isalpha(c)) {
        *w = c;
        *(w + 1) = '\0';
        return c;
    }
    *(w++) = c;
    for (; --lim > 0; w++) {
        c = getch();
        if (!isalnum(c)) {
            ungetch(c); // Возврат символа в поток
            break;
        }
        *w = c;
    }
    *w = '\0';
    return word[0];
}

char *w_tolower(char *w) {
    char *p = malloc(strlen(w) + 1);
    char *t;
    char *st;
    t = w;
    st = p;
    while (*t)
        *(st++) = tolower(*(t++));
    *st = '\0';
    return p;
}

int check_word(char *word) {
    char *mas_of_bad[6] = {"or", "and", "in", "as", "by", "at"};
    char *lower_word = w_tolower(word);
    for (int i = 0; i < 6; i++) {
        if (strcmp(lower_word, mas_of_bad[i]) == 0) {
            free(lower_word);
            return 0;
        }
    }
    free(lower_word);
    return 1;
}

void printtree(struct tnode *p) {
    if (p != NULL) {
        printtree(p->left);
        printf("%s ", p->word);
        for (int i = 0; i < p->last_el; i++) {
            printf("%d%c", p->num_str[i], (i == p->last_el - 1) ? '\n' : ' ');
        }
        printtree(p->right);
    }
}

void freetree(struct tnode *p) {
    if (p != NULL) {
        freetree(p->left);
        freetree(p->right);
        free(p->word); // Освобождаем память для слова
        free(p); // Освобождаем память для узла
    }
}

#define LIM_WORD 50
int main() {
    int ind = 1; // Начинаем с первой строки
    struct tnode *root = NULL;
    char word[LIM_WORD];
    char c;
    while ((c = getword(word, LIM_WORD)) != EOF) {
        if (c == '\n') {
            ind++;  // Увеличиваем индекс на новую строку
            continue;
        }
        if (isalpha(word[0]) && strlen(word) > 1 && check_word(word)) {
            root = addtree(root, word, ind);
        }
    }
    printtree(root); // Печать дерева
    freetree(root);  // Освобождение памяти
    return 0;
}
  • Вопрос задан
  • 111 просмотров
Подписаться 1 Простой Комментировать
Решения вопроса 1
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
В строке
while (isspace(c = getch())); // Пропуск пробелов
\n принимается за пробел и не возвращается из функции. В результате счётчик номеров строк не меняется.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы