Вы не можете выбрать более 25 тем
Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
149 строки
4.2 KiB
C++
149 строки
4.2 KiB
C++
#include <cctype>
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
#include <iostream>
|
|
#include <windows.h> // Äîáàâëåíî äëÿ ðàáîòû ñ êîäèðîâêîé
|
|
|
|
// Ìàêñèìóìû äëÿ áóôåðîâ (ñòåêîâûå ìàññèâû)
|
|
constexpr std::size_t kMaxFilenameLen = 260;
|
|
constexpr std::size_t kMaxQueryLen = 256;
|
|
|
|
// Íàáîð çàïðåùåííûõ ñèìâîëîâ äëÿ èìåíè ôàéëà (Windows)
|
|
constexpr const char* kForbidden = "*\"<>?|";
|
|
|
|
// Ïðîâåðêà âàëèäíîñòè èìåíè ôàéëà ïî ïðàâèëàì çàäàíèÿ
|
|
bool validate_filename(const char* name) {
|
|
// çàïðåòíûå ñèìâîëû
|
|
for (const char* p = kForbidden; *p; ++p) {
|
|
if (std::strchr(name, *p)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// äâîåòî÷èå
|
|
const char* colon = std::strchr(name, ':');
|
|
if (colon) {
|
|
if (colon != name + 1) return false; // òîëüêî âòîðîé ñèìâîë
|
|
if (!std::isalpha(static_cast<unsigned char>(name[0]))) return false;
|
|
if (colon[1] != '\\') return false; // çà äâîåòî÷èåì îáðàòíàÿ êîñàÿ
|
|
}
|
|
|
|
// ðàñøèðåíèå .txt (åñëè îíî åñòü)
|
|
const char* dot = std::strrchr(name, '.');
|
|
if (dot) {
|
|
if (std::strlen(dot) != 4) return false; // ".txt"
|
|
char ext[5]{};
|
|
// Èñïðàâëåíî: strncpy_s âìåñòî strncpy
|
|
strncpy_s(ext, sizeof(ext), dot, 4);
|
|
for (char& c : ext) c = static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
|
|
if (std::strcmp(ext, ".txt") != 0) return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// Äîáàâèòü .txt, åñëè òî÷êè íåò
|
|
void ensure_txt_extension(char* name, size_t bufferSize) {
|
|
if (std::strrchr(name, '.') == nullptr) {
|
|
// Èñïðàâëåíî: strcat_s âìåñòî strcat
|
|
strcat_s(name, bufferSize, ".txt");
|
|
}
|
|
}
|
|
|
|
// Ïîäñ÷èòàòü âõîæäåíèÿ ïîäñòðîêè sub â ñòðîêå text
|
|
int count_occurrences(const char* text, const char* sub) {
|
|
int count = 0;
|
|
const std::size_t len = std::strlen(sub);
|
|
if (len == 0) return 0;
|
|
|
|
const char* pos = text;
|
|
while ((pos = std::strstr(pos, sub)) != nullptr) {
|
|
++count;
|
|
pos += len;
|
|
}
|
|
return count;
|
|
}
|
|
|
|
int main() {
|
|
// Íàñòðîéêà êîäèðîâêè êîíñîëè äëÿ ðóññêîãî òåêñòà
|
|
SetConsoleOutputCP(1251);
|
|
SetConsoleCP(1251);
|
|
|
|
// 4.1: ââîä èìåíè ôàéëà (ñòåêîâûé áóôåð)
|
|
char filename[kMaxFilenameLen]{};
|
|
std::cout << "Ââåäèòå èìÿ ôàéëà: ";
|
|
std::cin.getline(filename, kMaxFilenameLen);
|
|
|
|
// 4.2: ïðîâåðêà êîððåêòíîñòè
|
|
if (!validate_filename(filename)) {
|
|
std::cout << "Íåêîððåêòíîå èìÿ ôàéëà\n";
|
|
return 1;
|
|
}
|
|
|
|
// 4.3: äîáàâèòü .txt ïðè îòñóòñòâèè
|
|
ensure_txt_extension(filename, sizeof(filename));
|
|
if (!validate_filename(filename)) {
|
|
std::cout << "Èìÿ íåêîððåêòíî ïîñëå äîáàâëåíèÿ .txt\n";
|
|
return 1;
|
|
}
|
|
|
|
// 4.4: ÷òåíèå ôàéëà ïîëíîñòüþ â äèíàìè÷åñêèé áóôåð
|
|
FILE* f = nullptr;
|
|
// Èñïðàâëåíî: fopen_s âìåñòî fopen
|
|
if (fopen_s(&f, filename, "rb") != 0 || !f) {
|
|
std::cout << "Íå óäàëîñü îòêðûòü ôàéë: " << filename << "\n";
|
|
return 1;
|
|
}
|
|
|
|
if (std::fseek(f, 0, SEEK_END) != 0) {
|
|
std::cout << "Îøèáêà ïåðåìåùåíèÿ â êîíåö ôàéëà\n";
|
|
std::fclose(f);
|
|
return 1;
|
|
}
|
|
|
|
long sz = std::ftell(f);
|
|
if (sz < 0) {
|
|
std::cout << "Íå óäàëîñü îïðåäåëèòü ðàçìåð ôàéëà\n";
|
|
std::fclose(f);
|
|
return 1;
|
|
}
|
|
std::rewind(f);
|
|
|
|
char* buffer = static_cast<char*>(std::malloc(static_cast<std::size_t>(sz) + 1));
|
|
if (!buffer) {
|
|
std::cout << "Íå óäàëîñü âûäåëèòü ïàìÿòü\n";
|
|
std::fclose(f);
|
|
return 1;
|
|
}
|
|
|
|
std::size_t read = std::fread(buffer, 1, static_cast<std::size_t>(sz), f);
|
|
if (read != static_cast<std::size_t>(sz)) {
|
|
std::cout << "Îøèáêà ÷òåíèÿ ôàéëà\n";
|
|
std::free(buffer);
|
|
std::fclose(f);
|
|
return 1;
|
|
}
|
|
buffer[sz] = '\0';
|
|
std::fclose(f);
|
|
|
|
// 4.5: ââîä èñêîìîé ñòðîêè (ñòåêîâûé áóôåð)
|
|
char query[kMaxQueryLen]{};
|
|
std::cout << "Ââåäèòå ñòðîêó äëÿ ïîèñêà: ";
|
|
std::cin.getline(query, kMaxQueryLen);
|
|
|
|
// 4.6: ïîäñ÷¸ò âõîæäåíèé
|
|
const std::size_t qlen = std::strlen(query);
|
|
if (qlen == 0) {
|
|
std::cout << "Ïóñòàÿ ñòðîêà ïîèñêà\n";
|
|
std::free(buffer);
|
|
return 1;
|
|
}
|
|
|
|
int hits = count_occurrences(buffer, query);
|
|
std::cout << "×èñëî âõîæäåíèé \"" << query << "\": " << hits << "\n";
|
|
|
|
// 4.7: îñâîáîæäåíèå ïàìÿòè
|
|
std::free(buffer);
|
|
return 0;
|
|
} |