Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * dict2.c -- программа чтения словаря и печати словарной статьи по шаблону
- *
- * Copyright (c) 2019, Arseniy Fomin <student@cs.karelia.ru>
- *
- * This code is licensed under a MIT-style license.
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #define MAXLINE 1023
- #define SEARCH_MODE_B 110
- #define SEARCH_MODE_E 101
- #define SEARCH_MODE_BE 211
- #define SIZE_OF_BUFFER 10 * 1024 * 1024
- char* load_dictionary(char *dictionary, FILE *stream);
- char* filter_dictionary(char *pattern, char *dictionary, char *entries);
- int main(int argc, char*argv[])
- {
- /* Файл словаря */
- FILE* dict = NULL;
- /* Диагностика ошибки неправильного числа аргументов */
- if (argc != 2) {
- fprintf(stderr, "Incorrect number of arguments.\n",
- "The correct input is: <dictionary_name>\n");
- exit(EXIT_FAILURE);
- }
- /* Открываем файл словаря */
- dict = fopen(argv[1], "r");
- /* Диагностика ошибок ввода-вывода */
- if (dict == NULL) {
- fprintf(stderr, "The program has closed due to I/O error.\n");
- exit(EXIT_FAILURE);
- }
- /* Создание буфера для загрузки файла и вывода результатов*/
- char *dict_buffer = NULL;
- char *entries_buffer = NULL;
- dict_buffer = (char *) malloc(sizeof(char) * SIZE_OF_BUFFER);
- entries_buffer = (char *) malloc(sizeof(char) * SIZE_OF_BUFFER);
- if ((dict_buffer == NULL) || (entries_buffer == NULL)) {
- fprintf(stderr, "Not enough memory for creating a buffer.\n",
- "The size required: 10MB\n");
- exit(EXIT_FAILURE);
- }
- /* Загрузка словаря и диагностика */
- char *qp_buffer = load_dictionary(dict_buffer, dict);
- if (qp_buffer == NULL) {
- fprintf(stderr, "The dictionary file is too large.\n",
- "The size limit: 10MB\n");
- exit(EXIT_FAILURE);
- }
- /* Завершаем работу с файлом словаря */
- fclose(dict);
- /* Шаблон для поиска */
- char query[MAXLINE + 1] = "";
- /* Получаем шаблон для поиска */
- printf("Enter the searching pattern:\n");
- scanf("%s", query);
- char *entries;
- memset(entries_buffer, '\0', SIZE_OF_BUFFER);
- /* Цикл ввода шаблонов */
- while (*query != '\0') {
- entries = filter_dictionary(query, qp_buffer, entries_buffer);
- if (entries == NULL)
- printf("No enties found.\n");
- else
- printf("%s\n", entries);
- memset(entries_buffer, '\0', SIZE_OF_BUFFER);
- memset(query, '\0', MAXLINE + 1);
- printf("Enter the searching pattern:\n");
- scanf("%s", query);
- }
- free(entries);
- free(dict_buffer);
- return 0;
- }
- char* filter_dictionary(char *pattern, char *dictionary, char *entries) {
- /* Текущая строка */
- char current_line[MAXLINE + 1] = "";
- /* Флаг для выбора режима поиска */
- int search_mode = 0;
- /* Определяем режим поиска */
- int pattern_len = strlen(pattern);
- if (pattern[0] == '^') {
- search_mode += SEARCH_MODE_B;
- memmove(pattern, pattern + 1, pattern_len - 1);
- pattern[pattern_len - 1] = '\0';
- pattern_len--;
- }
- if (pattern[pattern_len - 1] == '$') {
- search_mode += SEARCH_MODE_E;
- pattern[pattern_len - 1] = '\0';
- }
- /* Флаг соответствия текущей статьи условию отбора */
- int matched_entry = 0;
- char *line = dictionary;
- int sym_per_line = strcspn(line, "\n") + 1;
- strncpy(current_line, line, sym_per_line);
- line += sym_per_line;
- /* Просматриваем словарь */
- while (*line) {
- /* Если первый символ строки не является пробельным разделителем,
- найдено начало новой словарной статьи */
- if (!isspace(current_line[0])) {
- char *pointer = strstr(current_line, pattern);
- int cur_line_len = strlen(current_line) - 1;
- /* Определяем, выполнено ли условие отбора для данной статьи */
- switch (search_mode) {
- case SEARCH_MODE_B:
- if (pointer == current_line)
- matched_entry = 1;
- else
- matched_entry = 0;
- break;
- case SEARCH_MODE_E:
- if (pointer == current_line + cur_line_len - pattern_len)
- matched_entry = 1;
- else
- matched_entry = 0;
- break;
- case SEARCH_MODE_BE:
- if ((pointer == current_line) && (pattern_len == cur_line_len))
- matched_entry = 1;
- else
- matched_entry = 0;
- break;
- case 0:
- if (pointer != NULL)
- matched_entry = 1;
- else
- matched_entry = 0;
- break;
- }
- }
- /* Печатаем строку, если она относится к запрошенной статье */
- if (matched_entry) {
- strcat(entries, current_line);
- }
- sym_per_line = strcspn(line, "\n") + 1;
- strncpy(current_line, line, sym_per_line);
- line += sym_per_line;
- }
- if (strlen(entries) == 0)
- return NULL;
- else
- return entries;
- }
- char* load_dictionary(char *dictionary, FILE *stream) {
- /* Определение размера файла */
- fseek(stream, 0, SEEK_END);
- long dict_size = ftell(stream);
- rewind(stream);
- /* Копирование файла в буфер */
- fread(dictionary, 1, dict_size, stream);
- long buffer_size = strlen(dictionary);
- /* Проверка на целостность копирования */
- if (dict_size != buffer_size)
- return NULL;
- else
- return dictionary;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement