diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..84ea374 --- /dev/null +++ b/.clang-format @@ -0,0 +1,244 @@ +--- +Language: Cpp +# BasedOnStyle: WebKit +AccessModifierOffset: -4 +AlignAfterOpenBracket: DontAlign +AlignArrayOfStructures: None +AlignConsecutiveAssignments: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: true +AlignConsecutiveBitFields: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveDeclarations: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveMacros: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveShortCaseStatements: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCaseColons: false +AlignEscapedNewlines: Right +AlignOperands: DontAlign +AlignTrailingComments: + Kind: Never + OverEmptyLines: 0 +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowBreakBeforeNoexceptSpecifier: Never +AllowShortBlocksOnASingleLine: Empty +AllowShortCaseLabelsOnASingleLine: false +AllowShortCompoundRequirementOnASingleLine: true +AllowShortEnumsOnASingleLine: true +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: Never +AllowShortLambdasOnASingleLine: All +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: MultiLine +AttributeMacros: + - __capability +BinPackArguments: true +BinPackParameters: true +BitFieldColonSpacing: Both +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterExternBlock: false + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakAdjacentStringLiterals: true +BreakAfterAttributes: Leave +BreakAfterJavaFieldAnnotations: false +BreakArrays: true +BreakBeforeBinaryOperators: All +BreakBeforeConceptDeclarations: Always +BreakBeforeBraces: WebKit +BreakBeforeInlineASMColon: OnlyMultiline +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeComma +BreakInheritanceList: BeforeColon +BreakStringLiterals: true +ColumnLimit: 0 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: false +DerivePointerAlignment: false +DisableFormat: false +EmptyLineAfterAccessModifier: Never +EmptyLineBeforeAccessModifier: LogicalBlock +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: false +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IfMacros: + - KJ_IF_MAYBE +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + SortPriority: 0 + CaseSensitive: false + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + SortPriority: 0 + CaseSensitive: false + - Regex: '.*' + Priority: 1 + SortPriority: 0 + CaseSensitive: false +IncludeIsMainRegex: '(Test)?$' +IncludeIsMainSourceRegex: '' +IndentAccessModifiers: false +IndentCaseBlocks: false +IndentCaseLabels: false +IndentExternBlock: AfterExternBlock +IndentGotoLabels: true +IndentPPDirectives: None +IndentRequiresClause: true +IndentWidth: 4 +IndentWrappedFunctionNames: false +InsertBraces: false +InsertNewlineAtEOF: false +InsertTrailingCommas: None +IntegerLiteralSeparator: + Binary: 0 + BinaryMinDigits: 0 + Decimal: 0 + DecimalMinDigits: 0 + Hex: 0 + HexMinDigits: 0 +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +KeepEmptyLinesAtEOF: false +LambdaBodyIndentation: Signature +LineEnding: DeriveLF +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: Inner +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 4 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: true +ObjCSpaceBeforeProtocolList: true +PackConstructorInitializers: BinPack +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakOpenParenthesis: 0 +PenaltyBreakScopeResolution: 500 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyIndentedWhitespace: 0 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Left +PPIndentWidth: -1 +QualifierAlignment: Leave +ReferenceAlignment: Pointer +ReflowComments: true +RemoveBracesLLVM: false +RemoveParentheses: Leave +RemoveSemicolon: false +RequiresClausePosition: OwnLine +RequiresExpressionIndentation: OuterScope +SeparateDefinitionBlocks: Leave +ShortNamespaceLines: 1 +SkipMacroDefinitionBody: false +SortIncludes: CaseSensitive +SortJavaStaticImport: Before +SortUsingDeclarations: LexicographicNumeric +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceAroundPointerQualifiers: Default +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: true +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeJsonColon: false +SpaceBeforeParens: ControlStatements +SpaceBeforeParensOptions: + AfterControlStatements: true + AfterForeachMacros: true + AfterFunctionDefinitionName: false + AfterFunctionDeclarationName: false + AfterIfMacros: true + AfterOverloadedOperator: false + AfterPlacementOperator: true + AfterRequiresInClause: false + AfterRequiresInExpression: false + BeforeNonEmptyParentheses: false +SpaceBeforeRangeBasedForLoopColon: true +SpaceBeforeSquareBrackets: false +SpaceInEmptyBlock: true +SpacesBeforeTrailingComments: 1 +SpacesInAngles: Never +SpacesInContainerLiterals: true +SpacesInLineCommentPrefix: + Minimum: 1 + Maximum: -1 +SpacesInParens: Never +SpacesInParensOptions: + InCStyleCasts: false + InConditionalStatements: false + InEmptyParentheses: false + Other: false +SpacesInSquareBrackets: false +Standard: Latest +StatementAttributeLikeMacros: + - Q_EMIT +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 8 +UseTab: Never +VerilogBreakBetweenInstancePorts: true +WhitespaceSensitiveMacros: + - BOOST_PP_STRINGIZE + - CF_SWIFT_NAME + - NS_SWIFT_NAME + - PP_STRINGIZE + - STRINGIZE \ No newline at end of file diff --git a/.gitignore b/.gitignore index b48d248..83fa168 100644 --- a/.gitignore +++ b/.gitignore @@ -46,7 +46,7 @@ *.idb *.pdb -# Kernel Module Compile Results +# Kernel Module Comspile Results *.mod* *.cmd .tmp_versions/ @@ -54,5 +54,5 @@ modules.order Module.symvers Mkfile.old dkms.conf - +built # End of https://www.toptal.com/developers/gitignore/api/c diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..2ed5690 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.25) + +project(C_Homework) + +add_subdirectory(src/SortingStation) + +add_compile_options(-Wall -Wextra -Wpedantic) diff --git a/src/SortingStation/CMakeLists.txt b/src/SortingStation/CMakeLists.txt new file mode 100644 index 0000000..ed41c63 --- /dev/null +++ b/src/SortingStation/CMakeLists.txt @@ -0,0 +1,5 @@ +add_executable(sortingStation sortingStation.c) + +add_library(stack stack.c) + +target_link_libraries(sortingStation PRIVATE stack) diff --git a/src/SortingStation/sortingStation.c b/src/SortingStation/sortingStation.c new file mode 100644 index 0000000..b5e8bb6 --- /dev/null +++ b/src/SortingStation/sortingStation.c @@ -0,0 +1,101 @@ +#include "stack.h" +#include +#include +#include +#include + +// функция для определения приоритета операнда +- это 1, * / это 2 +int getPriority(char operand) +{ + if (operand == '+' || operand == '-') { + return 1; + } else if (operand == '*' || operand == '/') { + return 2; + } + return 0; +} + +char* convertString(char* string) +{ + struct Stack* stack = newStack(); + char* queue = malloc(1000 * sizeof(char)); + int len = strlen(string); + int queueEndPtr = 0; + int i = 0; + while (i != len) { + // если число + if (isdigit(string[i])) { + queue[queueEndPtr] = string[i]; + ++queueEndPtr; + queue[queueEndPtr] = ' '; + ++queueEndPtr; + } + // если открывающаяся скобка, добавляем ее в стек + if (string[i] == '(') { + push(stack, string[i]); + } + // если закрывающаяся, то переберем все значения стека и разместим их в очереди, пока не встретится открывающая скобка + else if (string[i] == ')') { + while ((!isEmpty(stack)) && (peek(stack) != '(')) { + queue[queueEndPtr] = pop(stack); + ++queueEndPtr; + queue[queueEndPtr] = ' '; + ++queueEndPtr; + } + if ((!isEmpty(stack)) && (peek(stack) == '(')) { + pop(stack); + } else if (!isEmpty(stack)) { + deleteStack(stack); + return "ERROR: you missed openning bracket symbol"; + } + } + // если операторы + - * / + if ((string[i] == '+') || (string[i] == '-') || (string[i] == '*') || (string[i] == '/')) { + // если оператор, но по приоритету такой же или меньший чем в стеке + while ((!isEmpty(stack)) && (getPriority(string[i]) <= getPriority(peek(stack)))) { + queue[queueEndPtr] = pop(stack); + ++queueEndPtr; + queue[queueEndPtr] = ' '; + ++queueEndPtr; + } + push(stack, string[i]); + } + ++i; + } + while (!isEmpty(stack)) { + if (peek(stack) == '(') { + deleteStack(stack); + return "ERROR: you missed closing bracket symbol"; + } + queue[queueEndPtr] = pop(stack); + ++queueEndPtr; + queue[queueEndPtr] = ' '; + ++queueEndPtr; + } + + deleteStack(stack); + // чтобы строка была корректной + queue[queueEndPtr] = '\0'; + char* queue_realloced = realloc(queue, sizeof(char) * (strlen(queue) + 1)); + free(stack); + return queue_realloced; +} + +/* + Предполагается, что пользователь вводит корректное арифметическое выражение. + Но в программе предусмотрено, если пользователь забудет одну из скобок. +*/ + +int main() +{ + char* arifmeticExpression = malloc(1001 * sizeof(char)); + // 1001 так как последний символ отводится для \0 + printf("Введите выражение, не превышающее по длине 1001 символов\n"); + fgets(arifmeticExpression, 1001, stdin); + char* queue = convertString(arifmeticExpression); + int queueLength = strlen(queue); + printf("%s\n", queue); + free(queue); + free(arifmeticExpression); + return 0; +} \ No newline at end of file diff --git a/src/SortingStation/stack.c b/src/SortingStation/stack.c new file mode 100644 index 0000000..d2a54ad --- /dev/null +++ b/src/SortingStation/stack.c @@ -0,0 +1,56 @@ +#include "stack.h" +#include +#include + +// структура обыкновенного элемента в стеке +typedef struct StackNode StackNode; + +struct StackNode { + int value; + struct StackNode* next; +}; + +// сам стек (структура содержащая указатель на первый элемент стека) +struct Stack { + struct StackNode* head; +}; + +Stack* newStack(void) +{ + Stack* stack = calloc(1, sizeof(*stack)); + return stack; +} + +void push(Stack* stack, int value) +{ + StackNode* node = malloc(sizeof(StackNode)); + node->value = value; + node->next = stack->head; + stack->head = node; +} + +int pop(Stack* stack) +{ + StackNode* oldNode = stack->head; + int res = oldNode->value; + stack->head = oldNode->next; + free(oldNode); + return res; +} + +int peek(struct Stack* stack) +{ + StackNode* headNode = stack->head; + int res = headNode->value; + return res; +} + +bool isEmpty(Stack* stack) { return stack->head == NULL; } + +void deleteStack(Stack* stack) +{ + while (!isEmpty(stack)) { + pop(stack); + } + free(stack); +} diff --git a/src/SortingStation/stack.h b/src/SortingStation/stack.h new file mode 100644 index 0000000..9a53d07 --- /dev/null +++ b/src/SortingStation/stack.h @@ -0,0 +1,49 @@ +#pragma once +#include + +// сам стек (структура содержащая указатель на первый элемент стека) +typedef struct Stack Stack; + +/* + * Функция создания "нового стека". + * Ничего не принимает. + * Возвращает указатель на созданный стек. + */ +Stack* newStack(void); + +/* + * Функция, добавляющая новый элемент в стек. + * Принимает указатель на стек и значение типа int + * Ничего не возвращает. + */ +void push(Stack* stack, int value); + +/* + * Функция извлечения элемента из стека. + * Принимает указатель на стек + * Возвращает значение из вершины стека и удаляет элемент. + * Ответственность за поведение программы при пустом стеке и попытке сделать + * к нему pop лежит на пользователе + */ +int pop(Stack* stack); + +/* + * Функция peek принимает на вход указатель на стек, + * Возвращает значение из вершины стека + */ +int peek(Stack* stack); + +/* + * Функция удаления стека (освобождения памяти). + * На вход принимает указатель на стек. + * Ничего не возвращает. + * Перебирает элементы стека и освобождает память, которую они занимают. + */ +void deleteStack(Stack* stack); + +/* + * функция проверяет, пустой ли стек + * на вход принимает указатель на стек + * возвращет булевое значение: true если стек пустой, иначе false + */ +bool isEmpty(Stack* stack);