Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Написать программу, которая должна читать входные данные из текстового файла (например, имеющего имя «input.txt»),
- * и выдавать результат работы в текстовый файл (например, имеющий имя «output.txt»).
- * Для ввода и вывода данных допускается использование в программе визуального интерфейса вместо файлового ввода/вывода.
- *
- * Вариант 1. На вход программы подается описание переменных на выбранном языке (Pascal, C++, C# и т.д.).
- * Программа должна проанализировать его при помощи регулярного выражения и выдать результат проверки.
- * При этом программа может быть написана на одном языке программирования,
- * но проверять правильность описания переменных на другом языке. Это может быть:
- * 1 Сообщение о том, что описание корректное;
- * 2 Сообщение о синтаксической ошибке. Указывать тип ошибки не обязательно,
- * требуется только указать строку и позицию в строке входного файла, где наблюдается ошибка.
- * Достаточно находить только первую ошибку в описании.
- * 3 Сообщение о дублировании имен переменных. В этом случае на выходе программы необходимо указать имя дублируемой
- * переменной, а также строку и позицию в строке, где встретился дубликат.
- */
- #include <iostream>
- #include <fstream>
- #include <regex>
- #include <string>
- #include <unordered_set>
- #include <windows.h>
- using namespace std;
- int main() {
- SetConsoleOutputCP(CP_UTF8);
- ifstream inputFile("input.txt");
- ofstream outputFile("output.txt");
- // Проверка успешности открытия файлов ввода/вывода.
- if (!inputFile.is_open() || !outputFile.is_open()) {
- cerr << "Не удалось открыть файлы ввода/вывода." << endl;
- return 1;
- }
- // Регулярное выражение для анализа описания переменных.
- string regexPattern =
- "\\b"
- /*
- * Это граница слова (word boundary). Это используется для того, чтобы удостовериться, что ключевые слова
- * (например, "int", "double") полностью соответствуют словам, а не являются частью других слов.
- */
- "(?:int|long int|double|float|char|short int|long double|long|short)?"
- /*
- * Это некаптурирующая группа, которая представляет собой ключевые слова для объявления переменных.
- * Знак вопроса в конце делает эту группу необязательной.
- */
- "\\s+"
- // Это один или более пробельных символов.
- "([a-zA-Z_][a-zA-Z0-9_]*)"
- /*
- * Это группа захвата для имени переменной. Она начинается с буквы или подчеркивания,
- * за которыми могут следовать буквы, цифры или подчеркивания.
- */
- "\\s*(?:\\[([0-9]+)\\])?"
- /*
- * Это некаптурирующая группа, представляющая собой опциональные квадратные скобки
- * с числовым значением внутри. Это может использоваться для обозначения размера массива.
- */
- "(?:\\[([0-9]+)\\])?\\s*(?:,\\s*([a-zA-Z_]\\w*)\\s*(?:\\[([0-9]+)\\])?(?:\\[([0-9]+)\\])?\\s*)*"
- /*
- * Это часть, которая позволяет определить
- * список переменных, разделенных запятой. Это повторяющаяся часть, где после первой переменной может
- * следовать запятая и дополнительные переменные.
- */
- ";";
- // Это точка с запятой в конце, обозначающая конец оператора объявления переменных.
- regex variablePattern(regexPattern);
- unordered_set<string> variableNames;
- string line;
- int lineNumber = 0;
- bool hasErrors = false;
- // Чтение файла построчно.
- while (getline(inputFile, line)) {
- lineNumber++;
- smatch match;
- // Поиск соответствия регулярному выражению в текущей строке.
- if (regex_search(line, match, variablePattern)) {
- // Проверка, соответствует ли вся строка описанию переменных.
- string syntaxCheck = match[0];
- if (syntaxCheck != line) {
- outputFile << "Синтаксическая ошибка в строке " << lineNumber << ", позиция " << (match.position() + 1)
- << endl;
- hasErrors = true;
- }
- // Проверка дубликатов имен переменных.
- for (size_t i = 1; i < match.size(); ++i) {
- string variables = match[i];
- istringstream variableStream(variables);
- string variableName;
- // Обработка списка переменных в текущей группе.
- while (getline(variableStream, variableName, ',')) {
- variableName.erase(remove_if(variableName.begin(), variableName.end(), ::isspace),
- variableName.end());
- // Проверка на дубликаты.
- if (variableNames.count(variableName) > 0) {
- outputFile << "Дублирование переменной '" << variableName << "' в строке " << lineNumber <<
- ", позиция " << (match.position(i) + 1) << endl;
- hasErrors = true;
- } else {
- variableNames.insert(variableName);
- }
- }
- }
- } else {
- // Вывод сообщения об ошибке, если не найдено соответствие регулярному выражению.
- outputFile << "Синтаксическая ошибка в строке " << lineNumber << ", позиция " << (match.position() + 1)
- << endl;
- hasErrors = true;
- }
- }
- // Вывод результата в файл.
- if (!hasErrors)
- outputFile << "Описание переменных корректное." << endl;
- // Закрытие файлов.
- inputFile.close();
- outputFile.close();
- cout << "Программа завершила выполнение." << endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment