Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

120 строки
3.6 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int is_valid_filename(char *name) {
// 1) Запрещённые символы
const char *forbidden = "*\"<>?|?";
for (const char *p = forbidden; *p; ++p) {
if (strchr(name, *p) != NULL)
return 0;
}
// 2) Двоеточие: только вторым символом, перед ним буква, после "\"
char *colon = strchr(name, ':');
if (colon) {
if (colon != name + 1) return 0; // не вторым
if (!isalpha((unsigned char)name[0])) return 0; // не буква
if (colon[1] != '\\') return 0; // нет '\'
}
// 3) Расширение: либо нет, либо .txt (в любом регистре)
char *dot = strrchr(name, '.');
if (dot) {
char ext[5] = {0};
strncpy(ext, dot, 4); // ".txt" + '\0'
for (int i = 0; ext[i]; ++i)
ext[i] = (char)tolower((unsigned char)ext[i]);
if (strcmp(ext, ".txt") != 0)
return 0;
}
return 1;
}
int main(void) {
char filename[260]; // 4.1: имя файла на стеке
char pattern[256]; // 4.5: строка поиска на стеке
printf("Enter the file name: ");
if (!fgets(filename, sizeof filename, stdin)) {
printf("Input error\n");
return 1;
}
// убрать '\n'
filename[strcspn(filename, "\n")] = '\0';
// 4.2: проверка имени
if (!is_valid_filename(filename)) {
printf("Incorrect file name\n");
return 1;
}
// 4.3: если нет расширения — добавить .txt
if (!strrchr(filename, '.')) {
if (strlen(filename) + 4 >= sizeof filename) {
printf("The file name is too long\n");
return 1;
}
strcat(filename, ".txt");
}
// 4.4: загрузка файла целиком
FILE *f = fopen(filename, "rb");
if (!f) {
printf("Failed to open file\n");
return 1;
}
if (fseek(f, 0, SEEK_END) != 0) { // в конец
printf("Error fseek\n");
fclose(f);
return 1;
}
long size = ftell(f); // размер файла в байтах
if (size < 0) {
printf("Error ftell\n");
fclose(f);
return 1;
}
rewind(f); // обратно в начало
char *text = (char*)malloc((size_t)size + 1); // +1 для '\0'
if (!text) {
printf("Out of memory\n");
fclose(f);
return 1;
}
size_t read_bytes = fread(text, 1, (size_t)size, f);
fclose(f);
text[read_bytes] = '\0'; // делаем Cстроку
// 4.5: строка для поиска
printf("Enter a search string: ");
if (!fgets(pattern, sizeof pattern, stdin)) {
printf("Input error\n");
free(text); // 4.7
return 1;
}
pattern[strcspn(pattern, "\n")] = '\0';
// 4.6: подсчёт вхождений pattern в text
int count = 0;
size_t pat_len = strlen(pattern);
if (pat_len > 0) {
char *pos = text;
while ((pos = strstr(pos, pattern)) != NULL) { // ищем подстроку
++count;
pos += pat_len; // идти дальше, можно pos+1, если нужны пересечения
}
}
printf("Number of occurrences: %d\n", count);
// 4.7: освобождение
free(text);
return 0;
}