Удвоить все гласные буквы в текстовом файле - C (СИ)
Формулировка задачи:
Вся задача:
1) записать файл из текстом
2) прочитать из файла текст
3) удвоить все гласные буквы
4) записать обратно в файл
Решение задачи: «Удвоить все гласные буквы в текстовом файле»
textual
Листинг программы
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
const char* vowels = "eyuioa";
int programFail(const char* message)
{
perror(message);
return -1;
}
typedef struct
{
char* buffer;
size_t length, bufferedTextLength;
} Buffer;
void initBuffer(Buffer* buf)
{
buf->length = 16;
buf->buffer = malloc(sizeof(char)*buf->length);
buf->bufferedTextLength = 0;
}
void writeEndBuffer(Buffer* buf, FILE* f)
{
int i = 0;
char c;
for(;i < buf->length; ++i)
{
c = buf->buffer[i];
if(strchr(vowels, c))
fputc(c, f);
fputc(c, f);
}
}
void writeBuffer(Buffer* buf, FILE* f)
{
size_t charCountWritten = 0, writeLimit = buf->length - buf->bufferedTextLength;
int i = 0, offsetOfUnwrittenData, skip = 0;
char c;
for(;charCountWritten < writeLimit; ++i)
{
c = buf->buffer[i];
if(strchr(vowels, c))
{
if (charCountWritten == (writeLimit - 1))
{
skip = 1;
break;
}
fputc(c, f);
++charCountWritten;
}
fputc(c, f);
++charCountWritten;
}
for(offsetOfUnwrittenData = i; i < (buf->length - skip); ++i)
buf->buffer[i - offsetOfUnwrittenData] = buf->buffer[i];
buf->bufferedTextLength = buf->length - offsetOfUnwrittenData - skip;
}
int readBuffer(Buffer* buf, FILE* f)
{
size_t newSize = buf->length;
size_t bytesRead = 0, bytesToRead;
long filePosition;
if(buf->bufferedTextLength > buf->length/2)
{
newSize = buf->length * sizeof(char) * 2;
buf->buffer = realloc(buf->buffer, newSize);
buf->length = newSize;
}
filePosition = ftell(f);
bytesToRead = newSize - buf->bufferedTextLength;
bytesRead = fread(buf->buffer + buf->bufferedTextLength, sizeof(char), bytesToRead , f);
fseek(f, filePosition, SEEK_SET);
if(bytesRead < bytesToRead)
{
buf->length = bytesRead + buf->bufferedTextLength;
buf->bufferedTextLength = 0;
return 0;
}
return 1;
}
void cleanupBuffer(Buffer* buf)
{
free(buf->buffer);
}
int main(int argc, char** argv)
{
Buffer buffer;
if(argc < 2)
return programFail("Missing file name command line argument");
FILE* f = fopen(argv[1], "r+");
if(f == NULL)
return programFail("Unable to open the file");
initBuffer(&buffer);
while(1)
{
if(readBuffer(&buffer, f))
writeBuffer(&buffer, f);
else
{
writeEndBuffer(&buffer, f);
break;
}
}
fclose(f);
cleanupBuffer(&buffer);
return 0;
}
Объяснение кода листинга программы
Код представляет собой программу, которая открывает указанный пользователем текстовый файл, считывает его содержимое построчно и удваивает все гласные буквы в каждой строке. Список элементов кода:
- Вектор
vowels, содержащий гласные буквы. - Функция
programFail, которая выводит сообщение об ошибке и возвращает код ошибки. - Структура
Buffer, которая представляет буфер для чтения и записи данных. - Функция
initBuffer, которая инициализирует буфер, выделяя память и устанавливая начальные значения его полей. - Функция
writeEndBuffer, которая записывает в файл символ конца строки и двойные гласные буквы из буфера. - Функция
writeBuffer, которая записывает в файл символы из буфера, удваивая гласные буквы. - Функция
readBuffer, которая считывает данные из файла в буфер, увеличивая размер буфера при необходимости. - Функция
cleanupBuffer, которая освобождает память, выделенную под буфер. - Функция
main, которая является точкой входа в программу. Она открывает указанный пользователем файл, инициализирует буфер, считывает данные из файла в буфер, записывает удвоенные гласные буквы обратно в файл и закрывает его. Примечание: Номера элементов списка соответствуют порядковым номерам в исходном коде.