Удалить из тестового файла строку с заданным номером - C (СИ)
Формулировка задачи:
Дано целое число K и текстовый файл. Удалить из файла строку с номером K. Если строки с таким номером нет, то оставить файл без изменений.
Решение задачи: «Удалить из тестового файла строку с заданным номером»
textual
Листинг программы
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum CONSTANTS {
SUCCESS,
NO_MEMORY,
NO_INPUT,
NO_OUTPUT,
LINE_MAX_LENGTH = 0xFF
}
int solve(const char name[], size_t k) {
const char ext[] = ".new";
const size_t LINE_MAX_LENGTH = 0xff;
char line[LINE_MAX_LENGTH + 1];
char * new_name;
size_t size, count;
int code = 0;
FILE* in, * out;
size = strlen(name) + strlen(ext) + 1;
new_name = (char*)calloc(size, sizeof(char));
if (NULL == new_name) {
code = NO_MEMORY;
goto do_clean_up;
}
in = fopen(name, "r");
if (NULL == in) {
code = NO_INPUT;
goto do_clean_up;
}
out = fopen(new_name, "w");
if (NULL == out) {
code = NO_OUTPUT;
goto do_clean_up;
}
count = 0;
while(NULL != fgets(line, LINE_MAX_LENGTH, in)) {
++count;
if (count == k) {
break;
}
fputs(line, out);
}
while(NULL != fgets(line, LINE_MAX_LENGTH, in)) {
fputs(line, out);
}
do_clean_up:
return clean_up(code, in, out, name, new_name);
}
int clean_up(int code, FILE* fin, FILE* out, const char* name, char* new_name) {
if (NULL != fin) fclose(fin);
if (NULL != out) fclose(out);
if (SUCCESS == code) {
remove(name);
rename(new_name, name);
}
free(new_name);
return code;
}
Объяснение кода листинга программы
- Включаются необходимые заголовочные файлы: stdio.h, stdlib.h, string.h
- Определяется константа LINE_MAX_LENGTH, которая имеет значение 0xFF (что соответствует 255).
- Функция solve принимает два аргумента: имя файла и номер строки, которую необходимо удалить.
- Внутри функции определяются следующие константы и переменные:
- ext[] - расширение нового файла (
.new) - LINE_MAX_LENGTH - максимальная длина строки, которая может быть прочитана из исходного файла (0xFF)
- line[] - массив символов, в котором будет храниться каждая строка из исходного файла
- new_name - новая строка, которая будет содержать имя нового файла
- size - переменная для хранения размера строки new_name
- count - счетчик количества прочитанных строк
- in, out - указатели на файлы для чтения из и записи в соответственно
- ext[] - расширение нового файла (
- Вычисляется размер строки new_name (к имени файла добавляется расширение
.new) - Выделяется память под новую строку new_name (если память не может быть выделена, то код функции меняется на NO_MEMORY)
- Открывается исходный файл для чтения (если файл не может быть открыт, то код функции меняется на NO_INPUT)
- Открывается новый файл для записи (если файл не может быть открыт, то код функции меняется на NO_OUTPUT)
- В цикле while считываются строки из исходного файла и записываются в новый файл до тех пор, пока не будет прочитано k строк (или пока не достигнут конец файла)
- В цикле while продолжается запись оставшихся строк из исходного файла в новый файл
- Если в процессе выполнения функции не возникло ошибок, то код функции меняется на SUCCESS.
- Если код функции SUCCESS, то исходный файл удаляется, а новый файл переименовывается в исходное имя файла.
- Если код функции не равен SUCCESS, то выполняется функция clean_up, которая закрывает файлы, освобождает память и возвращает код функции.
- Функция clean_up закрывает файлы, освобождает память и возвращает код функции.