Михаиллл3 февраля 2020 г. 13:31
При подключении файла получаю ошибки
Добрый день.
В проект на QT c++ пытаюсь подключить этот файл.
Если файл в проекте, но не подключен, то все компилируется, если делаю include, получаю пол сотни ошибок о множественном определении.
Помогите пожалуйста понять почему так и как это исправить.
//#ifndef ALGORITMHOFFMANA_H //#define ALGORITMHOFFMANA_H #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <stdarg.h> //#include "tchar.h" //using namespace std; // Константы, используемые в алгоритме кодирования #define END_OF_STREAM 256 /* Маркер конца потока */ #define ESCAPE 257 /* Маркер начала ESCAPE последовательности */ #define SYMBOL_COUNT 258 /* Максимально возможное количество листьев дерева (256+2 маркера)*/ #define NODE_TABLE_COUNT ((SYMBOL_COUNT * 2) - 1) #define ROOT_NODE 0 #define MAX_WEIGHT 0x8000 /* Вес корня, при котором начинается масштабирование веса */ #define TRUE 1 #define FALSE 0 #define PACIFIER_COUNT 2047 // шаг индикатора выполнения /* Коды ошибок */ #define NO_ERROR 0 #define BAD_FILE_NAME 1 #define BAD_ARGUMENT 2 // Эта структура данных нужна для побитового доступа к файлам typedef struct bit_file { FILE *file; unsigned char mask; int rack; int pacifier_counter; } COMPRESSED_FILE; // структура, описывающая узел дерева struct node { unsigned int weight; /* Вес узла */ int parent; /* Номер родителя в массиве узлов */ int child_is_leaf; /* Флаг листа (TRUE, если лист) */ int child; }; /* Эта структура данных используется для работы с деревом кодирования Хаффмана процедурами кодирования и декодирования */ typedef struct tree { int leaf[ SYMBOL_COUNT ]; /* Массив листьев дерева */ int next_free_node; /* Номер следующего свободного элемента массива листьев */ node nodes[ NODE_TABLE_COUNT ]; /* Массив узлов */ } TREE; // Сервисные функции void usage_exit (void); void print_ratios (char *input, char *output); long file_size (char *name); void fatal_error (char *fmt); // Функции побитового доступа к файлам COMPRESSED_FILE *OpenInputCompressedFile(char *name); COMPRESSED_FILE *OpenOutputCompressedFile(char *name); void OutputBit (COMPRESSED_FILE *, int bit); void OutputBits (COMPRESSED_FILE *bit_file, unsigned long code, int count); int InputBit (COMPRESSED_FILE *bit_file); unsigned long InputBits (COMPRESSED_FILE *bit_file, int bit_count); void CloseInputCompressedFile (COMPRESSED_FILE *bit_file); void CloseOutputCompressedFile (COMPRESSED_FILE *bit_file); // Собственно адаптивное кодирование Хаффмена void CompressFile (FILE *input, COMPRESSED_FILE *output); void ExpandFile (COMPRESSED_FILE *input, FILE *output); void InitializeTree (TREE *tree); void EncodeSymbol (TREE *tree, unsigned int c, COMPRESSED_FILE *output); int DecodeSymbol (TREE *tree, COMPRESSED_FILE *input); void UpdateModel (TREE *tree, int c); void RebuildTree (TREE *tree); void swap_nodes (TREE *tree, int i, int j); void add_new_node (TREE *tree, int c); //========================================================= //--------------------------------------------------------- // Вывод помощи о пользовании программой void help () { printf("HuffAdapt e(encoding)|d(decoding) input output\n"); } //--------------------------------------------------------- // Эта функция возвращает размер указанного ей файла #ifndef SEEK_END #define SEEK_END 2 #endif long file_size (char *name) { long eof_ftell; FILE *file; file = fopen(name, "r"); if (file == NULL) return(0L); fseek(file, 0L, SEEK_END); eof_ftell = ftell(file); fclose(file); return(eof_ftell); } //--------------------------------------------------------- /* Эта фунцция выводит результаты сжатия после окончания сжатия */ void print_ratios (char *input, char *output) { long input_size; long output_size; int ratio; input_size = file_size(input); if (input_size == 0) input_size = 1; output_size = file_size(output); ratio = 100 - (int) (output_size * 100L / input_size); printf("\nSource filesize:\t%ld\n", input_size); printf("Target Filesize:\t%ld\n", output_size); if (output_size == 0) output_size = 1; printf("Compression ratio:\t\t%d%%\n", ratio); } //--------------------------------------------------------- // вывод сообщения об ошибке void fatal_error (char *fmt) { printf("Fatal error: "); printf("%s",fmt); exit(-1); }; //--------------------------------------------------------- // открытие файла для побитового вывода COMPRESSED_FILE *OpenOutputCompressedFile(char *name) { COMPRESSED_FILE *compressed_file; compressed_file = (COMPRESSED_FILE *) calloc(1, sizeof(COMPRESSED_FILE)); if (compressed_file == NULL) return(compressed_file); compressed_file->file = fopen(name, "wb"); compressed_file->rack = 0; compressed_file->mask = 0x80; compressed_file->pacifier_counter = 0; return(compressed_file); } //--------------------------------------------------------- //Открытие файла для побитового ввода COMPRESSED_FILE *OpenInputCompressedFile (char *name) { COMPRESSED_FILE *compressed_file; compressed_file = (COMPRESSED_FILE *) calloc(1, sizeof(COMPRESSED_FILE)); if (compressed_file == NULL) return(compressed_file); compressed_file->file = fopen(name, "rb"); compressed_file->rack = 0; compressed_file->mask = 0x80; compressed_file->pacifier_counter = 0; return(compressed_file); } //--------------------------------------------------------- //Закрытие файла для побитового вывода void CloseOutputCompressedFile(COMPRESSED_FILE *compressed_file) { if (compressed_file->mask != 0x80) if (putc(compressed_file->rack, compressed_file->file) != compressed_file->rack) fatal_error("Error on close compressed file.\n"); fclose(compressed_file->file); free((char *) compressed_file); } //--------------------------------------------------------- // Закрытие файла для побитового ввода void CloseInputCompressedFile(COMPRESSED_FILE *compressed_file) { fclose(compressed_file->file); free((char *) compressed_file); } //--------------------------------------------------------- // Вывод одного бита void OutputBit(COMPRESSED_FILE *compressed_file, int bit) { if (bit) compressed_file->rack |= compressed_file->mask; compressed_file->mask >>= 1; if (compressed_file->mask == 0) { if (putc(compressed_file->rack, compressed_file->file) != compressed_file->rack) fatal_error("Error on OutputBit!\n"); else if ((compressed_file->pacifier_counter++ & PACIFIER_COUNT) == 0) putc('.', stdout); compressed_file->rack = 0; compressed_file->mask = 0x80; } } //--------------------------------------------------------- // Вывод нескольких битов void OutputBits(COMPRESSED_FILE *compressed_file, unsigned long code, int count) { unsigned long mask; mask = 1L << (count - 1); while (mask != 0) { if (mask & code) compressed_file->rack |= compressed_file->mask; compressed_file->mask >>= 1; if (compressed_file->mask == 0) { if (putc(compressed_file->rack, compressed_file->file)!= compressed_file->rack) fatal_error("Error on OutputBits!\n"); else if ((compressed_file->pacifier_counter++ & PACIFIER_COUNT) == 0) putc('.', stdout); compressed_file->rack = 0; compressed_file->mask = 0x80; } mask >>= 1; } } //--------------------------------------------------------- // Ввод одного бита int InputBit (COMPRESSED_FILE *compressed_file) { int value; if (compressed_file->mask == 0x80) { compressed_file->rack = getc(compressed_file->file); if (compressed_file->rack == EOF) fatal_error("Error on InputBit!\n"); if ((compressed_file->pacifier_counter++ & PACIFIER_COUNT) == 0) putc('.', stdout); } value = compressed_file->rack & compressed_file->mask; compressed_file->mask >>= 1; if (compressed_file->mask == 0) compressed_file->mask = 0x80; return(value ? 1 : 0); } //--------------------------------------------------------- // Ввод нескольких битов unsigned long InputBits (COMPRESSED_FILE *compressed_file, int bit_count) { unsigned long mask; unsigned long return_value; mask = 1L << (bit_count - 1); return_value = 0; while (mask != 0) { if (compressed_file->mask == 0x80) { compressed_file->rack = getc(compressed_file->file); if (compressed_file->rack == EOF) fatal_error("Error on InputBits!\n"); if ((compressed_file->pacifier_counter++ & PACIFIER_COUNT) == 0) putc('.', stdout); } if (compressed_file->rack & compressed_file->mask) return_value |= mask; mask >>= 1; compressed_file->mask >>= 1; if (compressed_file->mask == 0) compressed_file->mask = 0x80; } return (return_value); } //========================================================= /* С этого места начинается исходный текст, * реализующий собственно алгоритм * адаптивного кодирования Хаффмана */ TREE Tree; //Дерево адаптивного кодирования Хаффмена // Функция преобразования входного файла в выходной сжатый файл void CompressFile(FILE *input, COMPRESSED_FILE *output) { int c; InitializeTree(&Tree); while ((c = getc(input)) != EOF) { EncodeSymbol(&Tree, c, output); UpdateModel(&Tree, c); } EncodeSymbol(&Tree, END_OF_STREAM, output); } //--------------------------------------------------------- // Процедура декомпрессии упакованного файла void ExpandFile (COMPRESSED_FILE *input, FILE *output) { int c; InitializeTree(&Tree); while ((c = DecodeSymbol(&Tree, input)) != END_OF_STREAM) { if (putc(c, output) == EOF) fatal_error("Error on output"); UpdateModel(&Tree, c); } } //--------------------------------------------------------- /* Функция инициализации дерева Перед началом работы алгоритма дерево кодирования инициализируется двумя специальными (не ASCII) символами: ESCAPE и END_OF_STREAM. Также инициализируется корень дерева. Все листья инициализируются -1, так как они еще не присутствуют в дереве кодирования. */ void InitializeTree (TREE *tree) { int i; tree->nodes[ ROOT_NODE ].child = ROOT_NODE + 1; tree->nodes[ ROOT_NODE ].child_is_leaf = FALSE; tree->nodes[ ROOT_NODE ].weight = 2; tree->nodes[ ROOT_NODE ].parent = -1; tree->nodes[ ROOT_NODE + 1 ].child = END_OF_STREAM; tree->nodes[ ROOT_NODE + 1 ].child_is_leaf = TRUE; tree->nodes[ ROOT_NODE + 1 ].weight = 1; tree->nodes[ ROOT_NODE + 1 ].parent = ROOT_NODE; tree->leaf[ END_OF_STREAM ] = ROOT_NODE + 1; tree->nodes[ ROOT_NODE + 2 ].child = ESCAPE; tree->nodes[ ROOT_NODE + 2 ].child_is_leaf = TRUE; tree->nodes[ ROOT_NODE + 2 ].weight = 1; tree->nodes[ ROOT_NODE + 2 ].parent = ROOT_NODE; tree->leaf[ ESCAPE ] = ROOT_NODE + 2; tree->next_free_node = ROOT_NODE + 3; for (i = 0 ; i < END_OF_STREAM ; i++) tree->leaf[ i ] = -1; } //--------------------------------------------------------- /* Эта процедура преобразует входной символ в последовательность битов на основе текущего состояния дерева кодирования. Некоторое неудобство состоит в том, что, обходя дерево от листа к корню, мы получаем последовательность битов в обратном порядке, и поэтому необходимо аккумулировать биты в INTEGER переменной и выдавать их после того, как обход дерева закончен. */ void EncodeSymbol (TREE *tree, unsigned int c, COMPRESSED_FILE *output) { unsigned long code; unsigned long current_bit; int code_size; int current_node; code = 0; current_bit = 1; code_size = 0; current_node = tree->leaf[ c ]; if (current_node == -1) current_node = tree->leaf[ ESCAPE ]; while (current_node != ROOT_NODE) { if ((current_node & 1) == 0) code |= current_bit; current_bit <<= 1; code_size++; current_node = tree->nodes[ current_node ].parent; } OutputBits(output, code, code_size); if (tree->leaf[ c ] == -1) { OutputBits(output, (unsigned long) c, 8); add_new_node(tree, c); } } //--------------------------------------------------------- /* Процедура декодирования очень проста. Начиная от корня, мы обходим дерево, пока не дойдем до листа. Затем проверяем не прочитали ли мы ESCAPE код. Если да, то следующие 8 битов соответствуют незакодированному символу, который немедленно считывается и добавляется к таблице. */ int DecodeSymbol (TREE *tree, COMPRESSED_FILE *input) { int current_node; int c; current_node = ROOT_NODE; while (!tree->nodes[ current_node ].child_is_leaf) { current_node = tree->nodes[ current_node ].child; current_node += InputBit(input); } c = tree->nodes[ current_node ].child; if (c == ESCAPE) { c = (int) InputBits(input, 8); add_new_node(tree, c); } return(c); } //--------------------------------------------------------- /* Процедура обновления модели кодирования для данного символа, пожалуй, самое сложное в адаптивном кодировании Хаффмана. */ void UpdateModel (TREE *tree, int c) { int current_node; int new_node; if (tree->nodes[ ROOT_NODE].weight == MAX_WEIGHT) RebuildTree(tree); current_node = tree->leaf[ c ]; while (current_node != -1) { tree->nodes[ current_node ].weight++; for (new_node=current_node;new_node>ROOT_NODE;new_node--) if (tree->nodes[ new_node - 1 ].weight >= tree->nodes[ current_node ].weight) break; if (current_node != new_node) { swap_nodes(tree, current_node, new_node); current_node = new_node; } current_node = tree->nodes[ current_node ].parent; } } //--------------------------------------------------------- /* Процедура перестроения дерева вызывается тогда, когда вес корня дерева достигает пороговой величины. Она начинается с простого деления весов узлов на 2. Но из-за ошибок округления при этом может быть нарушено свойство упорядоченности дерева кодирования, и необходимы дополнительные усилия, чтобы привести его в корректное состояние. */ void RebuildTree (TREE *tree) { int i; int j; int k; unsigned int weight; printf("R"); j = tree->next_free_node - 1; for (i = j ; i >= ROOT_NODE ; i--) { if (tree->nodes[ i ].child_is_leaf) { tree->nodes[ j ] = tree->nodes[ i ]; tree->nodes[ j ].weight = (tree->nodes[ j ].weight + 1) / 2; j--; } } for (i = tree->next_free_node-2; j >= ROOT_NODE; i-=2, j--) { k = i + 1; tree->nodes[ j ].weight = tree->nodes[ i ].weight + tree->nodes[ k ].weight; weight = tree->nodes[ j ].weight; tree->nodes[ j ].child_is_leaf = FALSE; for (k = j + 1 ; weight < tree->nodes[ k ].weight ; k++) ; k--; memmove(&tree->nodes[ j ], &tree->nodes[ j + 1 ], (k - j) * sizeof(struct node)); tree->nodes[ k ].weight = weight; tree->nodes[ k ].child = i; tree->nodes[ k ].child_is_leaf = FALSE; } for (i = tree->next_free_node - 1 ; i >= ROOT_NODE ; i--) { if (tree->nodes[ i ].child_is_leaf) { k = tree->nodes[ i ].child; tree->leaf[ k ] = i; } else { k = tree->nodes[ i ].child; tree->nodes[ k ].parent = tree->nodes[ k + 1 ].parent = i; } } } //--------------------------------------------------------- /* Процедура перестановки узлов дерева вызывается тогда, когда очередное увеличение веса узла привело к нарушению свойства упорядоченности. */ void swap_nodes (TREE *tree, int i, int j) { node temp; if (tree->nodes[ i ].child_is_leaf) tree->leaf[ tree->nodes[ i ].child ] = j; else { tree->nodes[ tree->nodes[ i ].child ].parent = j; tree->nodes[ tree->nodes[ i ].child + 1 ].parent = j; } if (tree->nodes[ j ].child_is_leaf) tree->leaf[ tree->nodes[ j ].child ] = i; else { tree->nodes[ tree->nodes[ j ].child ].parent = i; tree->nodes[ tree->nodes[ j ].child + 1 ].parent = i; } temp = tree->nodes[ i ]; tree->nodes[ i ] = tree->nodes[ j ]; tree->nodes[ i ].parent = temp.parent; temp.parent = tree->nodes[ j ].parent; tree->nodes[ j ] = temp; } //--------------------------------------------------------- /* Добавление нового узла в дерево осуществляется достаточно просто. Для этого "самый легкий" узел дерева разбивается на 2, один из которых и есть тот новый узел. Новому узлу присваивается вес 0, котрый будет изменен потом, при нормальном процессе обновления дерева. */ void add_new_node (TREE *tree, int c) { int lightest_node; int new_node; int zero_weight_node; lightest_node = tree->next_free_node - 1; new_node = tree->next_free_node; zero_weight_node = tree->next_free_node + 1; tree->next_free_node += 2; tree->nodes[ new_node ] = tree->nodes[ lightest_node ]; tree->nodes[ new_node ].parent = lightest_node; tree->leaf[ tree->nodes[ new_node ].child ] = new_node; tree->nodes[ lightest_node ].child = new_node; tree->nodes[ lightest_node ].child_is_leaf = FALSE; tree->nodes[ zero_weight_node ].child = c; tree->nodes[ zero_weight_node ].child_is_leaf = TRUE; tree->nodes[ zero_weight_node ].weight = 0; tree->nodes[ zero_weight_node ].parent = lightest_node; tree->leaf[ c ] = zero_weight_node; } //------------------------------------------------------- /* Функция Main осуществляет разбор командной строки и проверку при открытии входного и выходного файла. */ int _tmain(int argc, char* argv[]) { // проверка аргументов if (argc!=4){ help(); exit(BAD_ARGUMENT); } else if ( tolower(argv[1][0])!= 'e' && tolower(argv[1][0])!= 'd'){ help(); exit(BAD_ARGUMENT); } else{ if (tolower(argv[1][0]) == 'e'){ // компрессия COMPRESSED_FILE *output; FILE *input; input = fopen(argv[ 2 ], "rb"); if (input == NULL) fatal_error("Error open source file.\n"); output = OpenOutputCompressedFile(argv[ 3 ]); if (output == NULL) fatal_error("Error open target file.s\n"); CompressFile(input, output); CloseOutputCompressedFile(output); fclose(input); print_ratios(argv[ 2 ], argv[ 3 ]); } else{ // декомпрессия FILE *output; COMPRESSED_FILE *input; input = OpenInputCompressedFile(argv[ 2 ]); if (input == NULL) fatal_error("Error open source file.\n"); output = fopen(argv[ 3 ], "wb"); if (output == NULL) fatal_error("Error open target file.s\n"); ExpandFile(input, output); CloseInputCompressedFile(input); fclose(output); }; }; printf("Completed.\n"); return (NO_ERROR); } //#endif // ALGORITMHOFFMANA_H
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.Вам это нравится? Поделитесь в социальных сетях!
Комментарии
Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь
Пожалуйста, авторизуйтесь или зарегистрируйтесь
AD
- Akiv Doros
- 12 ноября 2024 г. 1:58
C++ - Тест 004. Указатели, Массивы и Циклы
- Результат:50баллов,
- Очки рейтинга-4
m
- molni99
- 26 октября 2024 г. 11:37
C++ - Тест 004. Указатели, Массивы и Циклы
- Результат:80баллов,
- Очки рейтинга4
m
- molni99
- 26 октября 2024 г. 11:29
C++ - Тест 004. Указатели, Массивы и Циклы
- Результат:20баллов,
- Очки рейтинга-10
Последние комментарии
Django - Урок 055. Как написать функционал auto populate field Freckles because of several brand names retin a, atralin buy generic priligy
QML - Урок 035. Использование перечислений в QML без C++ priligy cvs 24 Together with antibiotics such as amphotericin B 10, griseofulvin 11 and streptomycin 12, chloramphenicol 9 is in the World Health Organisation s List of Essential Medici…
Qt/C++ - Урок 052. Кастомизация Qt Аудио плеера в стиле AIMP It decreases stress, supports hormone balance, and regulates and increases blood flow to the reproductive organs buy priligy online safe Promising data were reported in a PDX model re…
Алгоритм сортировки кучей The role of raloxifene in preventing breast cancer priligy precio
PyQt5 - Урок 006. Работа с QTableWidget buy priligy 60 mg 53 have been reported by Javanovic Santa et al
Сейчас обсуждают на форуме
добавить qlineseries в функции buy priligy senior brother Chu He, whom he had known for many years
Всё ещё разбираюсь с кешем. priligy walgreens levitra dulcolax carbs The third ring was found to be made up of ultra relativistic electrons, which are also present in both the outer and inner rings
IscanderChe1 ноября 2024 г. 1:43
Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…
ИМ
Реализация навигации по разделам Спасибо Евгений!
Игорь Максимов3 октября 2024 г. 14:05
Похоже это оказался чистый С, отдельно без библиотек Qt он запускается. Похоже для использования в программе его нужно переделывать.
Обычно для си кода используют extern модификаторы, чтобы можно было его использовать в C++ проектах.
Нужно ко всем объявлениям переменных и функций добавить extern ?
Что-то типо такого попробуйте
Попробовал так, все равно выдает теже ошибки
какие ошибки?
Множественное определение. Переделал все в с++ классы, пока ошибок подобных нет.
аа. ну если вы всё в C++ переделали и у вас теперь нет множественного определения, то лучше используйте C++ классы, как сделали. Это будет лучше.