Скопировать содержимое, ограничив длину строки N символами - C (СИ)
Формулировка задачи:
Всем доброго времени суток, нужна помощь с задачей: "Скопировать содержимое текстового файла, ограничив длину строки N символами. Слова, не помещающиеся в заданную строку не копировать." Поработав с программами, найденными в интернете получил две разные программы:
1)
2)
И всё бы ничего, но обе программы просто обрывают слова на середине, если эти слова не влезают в длину, а нужно, чтобы если слово не помещалось, то оно целиком и полностью удалялось.
Посидев, пораскинув мозгами прикинул следующую схему:
1) Копируем текстовый документ 1.txt, работаем с каждой строкой по очереди;
2) В общем цикле для работы с каждой строкой: Разбивать строку на слова, слова заносить в массив, а дальше в цикле сравнивать длину i первых слов в массиве (с пробелами) с числом N. Если i < N, то идти дальше. Если i > N, то если кол-во слов больше одного, то записывать [i-1] слов из массива в строку и переходить к следующей строке. Ну или как-то так.
На словах, как говорится, Лев Толстой... А время поджимает.
Попробовав реализовать, понял, что проблема в моих знаниях и опыте. Буду очень благодарен, если доделаете мою программу или предложите свой вариант.
Мои наработки:
Листинг программы
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #define LEN_STR 1024
- #define N 5
- char seps[10] = " ,.!?:;'\n";
- char* text;
- char* temp;
- FILE* source;
- FILE* target;
- void main(void)
- {
- source = fopen("1.txt", "rt");
- target = fopen("2.txt", "wt");
- text = (char*)calloc(LEN_STR, 1);
- temp = (char*)calloc(LEN_STR, 1);
- while (!feof(source))
- {
- fgets(text, LEN_STR, source);
- strncpy(temp, text, N);
- if (strlen(text) > N)
- {
- temp[N] = '\n';
- temp[N + 1] = 0;
- }
- fputs(temp, target);
- }
- fclose(source);
- fclose(target);
- free(text);
- free(temp);
- }
Листинг программы
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #define MAXLEN 4 //Макс. длина строки
- int main(void)
- {
- char c=0; //Хранится символ из входного файла, вспомогательная переменная
- char String[MAXLEN + 1];
- char *pathFileInput=(char*)calloc(20, sizeof(char));
- char *pathFileOutput=(char*)calloc(20, sizeof(char));
- FILE *fileInput; //Файловая переменная для входного файла
- FILE *fileOutput; //Файловая переменная для выходного файла
- fileInput=fopen("1.txt", "rt");
- fileOutput= fopen("2.txt", "wt");
- while(c!=EOF)
- {
- fgets(String,MAXLEN + 1,fileInput);
- fputs(String,fileOutput);
- fputc('\n', fileOutput);
- while (c != '\n' && c != EOF)
- c = fgetc(fileInput);
- if (c!=EOF) //Если это не признак конца файла, c = пробел (или любой другой неслужебный символ
- c=' '; //иначе мы застрянем во вложенном while на след. итерации
- }
- free(pathFileInput);
- free(pathFileOutput);
- fclose (fileInput);
- fclose(fileOutput);
- return 0;
- }
Листинг программы
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #define LEN_STR 1024
- #define N 5
- char seps[10] = " ,.!?:;'\n";
- char* text;
- char* temp;
- char* word;
- FILE* source;
- FILE* target;
- char* data[100];
- void main(void)
- {
- source = fopen("1.txt", "rt");
- target = fopen("2.txt", "wt");
- text = (char*)calloc(LEN_STR, 1);
- temp = (char*)calloc(LEN_STR, 1);
- while (!feof(source))
- {
- fgets(text, LEN_STR, source);
- //Заимствуем код из программы, удаляющей слова, больше определённого размера
- //last = temp;
- //word = strtok(temp, seps);
- //while (word)
- //{
- // strncat(res, text + (last - temp), word - last);
- // if (strlen(word) <= N)
- // strcat(res, word);
- //
- // last = word + strlen(word);
- // word = strtok(NULL, seps);
- //}
- //strcat(res, text + (last - temp));
- word = strtok(temp, seps);
- while (word)
- {
- data = data + word;
- if (strlen(data) > N)
- {
- temp[N] = '\n';
- temp[N + 1] = 0;
- }
- fputs(temp, target);
- word = strtok(NULL, seps);
- }
- strcat(res, text + (last - temp));
- }
- fclose(source);
- fclose(target);
- free(text);
- free(temp);
- }
Решение задачи: «Скопировать содержимое, ограничив длину строки N символами»
textual
Листинг программы
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
- #include <stdlib.h>
- #define DEFAULT_OUTPUT_WIDTH (80)
- #define PROGRAM_NAME argv[0]
- #define INPUT_FILE_NAME argv[1]
- #define OUTPUT_FILE_NAME argv[2]
- #define OUTPUT_WIDTH argv[3]
- #define INPUT_BUFFER_SIZE (2048)
- int main(int argc, char ** argv) {
- FILE * fIn, * fOut;
- char * bufIn, * bufOut, * posPtr;
- size_t inpLen, outLen, tmpLen;
- if ( argc < 2 ) {
- fprintf(stderr, "USAGE: %s input_file [output_file [width]]\n", PROGRAM_NAME);
- exit(EXIT_FAILURE);
- }
- if ( argc == 4 ) {
- outLen = atoi(OUTPUT_WIDTH);
- if ( outLen < 1 || outLen >= INPUT_BUFFER_SIZE ) {
- fprintf(stderr, "%s: wrong parameter to output width - %lu\n", PROGRAM_NAME, outLen);
- exit(EXIT_FAILURE);
- }
- }
- else
- outLen = DEFAULT_OUTPUT_WIDTH;
- if ( ! ( bufIn = malloc(INPUT_BUFFER_SIZE) ) ) {
- perror("malloc");
- exit(EXIT_FAILURE);
- }
- if ( ! ( bufOut = malloc(outLen + 2) ) ) {
- free(bufIn);
- perror("malloc");
- exit(EXIT_FAILURE);
- }
- if ( ! ( fIn = fopen(INPUT_FILE_NAME, "r") ) ) {
- fprintf(stderr, "%s: can't open file %s for input!\n", PROGRAM_NAME, INPUT_FILE_NAME);
- free(bufIn);
- free(bufOut);
- exit(EXIT_FAILURE);
- }
- if ( argc == 2 )
- fOut = stdout;
- else {
- if ( ! ( fOut = fopen(OUTPUT_FILE_NAME, "w") ) ) {
- fprintf(stderr, "%s: can't open file %s for output!\n", PROGRAM_NAME, OUTPUT_FILE_NAME);
- fclose(fIn);
- free(bufIn);
- free(bufOut);
- exit(EXIT_FAILURE);
- }
- }
- while ( fgets(bufIn, INPUT_BUFFER_SIZE, fIn) ) {
- while ( ( inpLen = strlen(bufIn) ) > outLen ) {
- for ( posPtr = bufIn + outLen - 1; posPtr >= bufIn && ! isspace(*posPtr); --posPtr )
- ;
- if ( posPtr < bufIn ) {
- memcpy(bufOut, bufIn, outLen);
- bufOut[outLen] = '\n';
- bufOut[outLen + 1] = '\0';
- if ( fprintf(fOut, "%s", bufOut) == EOF ) {
- fprintf(stderr, "%s: can't write to output file!\n", PROGRAM_NAME);
- if ( fclose(fIn) )
- perror("While close input file");
- if ( fclose(fOut) )
- perror("While close output file");
- free(bufIn);
- free(bufOut);
- exit(EXIT_FAILURE);
- }
- memmove(bufIn, bufIn + outLen, strlen(bufIn + outLen) + 1);
- }
- else {
- tmpLen = posPtr - bufIn;
- memcpy(bufOut, bufIn, tmpLen);
- bufOut[tmpLen] = '\n';
- bufOut[tmpLen + 1] = '\0';
- if ( fprintf(fOut, "%s", bufOut) == EOF ) {
- fprintf(stderr, "%s: can't write to output file!\n", PROGRAM_NAME);
- if ( fclose(fIn) )
- perror("While close input file");
- if ( fclose(fOut) )
- perror("While close output file");
- free(bufIn);
- free(bufOut);
- exit(EXIT_FAILURE);
- }
- memmove(bufIn, bufIn + tmpLen + 1, strlen(bufIn + tmpLen));
- }
- }
- if ( inpLen ) {
- if ( fprintf(fOut, "%s", bufIn) == EOF ) {
- fprintf(stderr, "%s: can't write to output file!\n", PROGRAM_NAME);
- if ( fclose(fIn) )
- perror("While close input file");
- if ( fclose(fOut) )
- perror("While close output file");
- free(bufIn);
- free(bufOut);
- exit(EXIT_FAILURE);
- }
- }
- }
- if ( ferror(fIn) ) {
- fprintf(stderr, "%s: error while reading input file!\n", PROGRAM_NAME);
- if ( fclose(fIn) )
- perror("While close input file");
- if ( fclose(fOut) )
- perror("While close output file");
- free(bufIn);
- free(bufOut);
- exit(EXIT_FAILURE);
- }
- if ( fclose(fIn) )
- perror("While close input file");
- if ( fOut != stdout && fclose(fOut) )
- perror("While close output file");
- free(bufIn);
- free(bufOut);
- exit(EXIT_SUCCESS);
- }
Объяснение кода листинга программы
Этот код предназначен для копирования содержимого из одного файла в другой с ограничением на количество символов в каждой строке. Он использует стандартные библиотеки C и может быть скомпилирован с помощью любого компилятора C. Список переменных и их значений:
- argc - количество аргументов в командной строке (обычно 2 или 4)
- argv - массив строк, содержащих параметры командной строки
- PROGRAM_NAME - имя программы (обычно имя исполняемого файла)
- INPUT_FILE_NAME - имя входного файла
- OUTPUT_FILE_NAME - имя выходного файла (если не указано, то это stdout)
- OUTPUT_WIDTH - ширина вывода (если не указано, то это 80)
- DEFAULT_OUTPUT_WIDTH - значение по умолчанию для OUTPUT_WIDTH, равное 80
- INPUT_BUFFER_SIZE - размер буфера ввода, равный 2048
- fIn - файловый указатель на входной файл
- fOut - файловый указатель на выходной файл (может быть stdout)
- bufIn - указатель на буфер ввода
- bufOut - указатель на буфер вывода
- inpLen - длина строки в буфере ввода
- outLen - длина строки в буфере вывода
- tmpLen - временная переменная для хранения длины строки
- posPtr - указатель на текущую позицию в строке
- isspace - функция, проверяющая, является ли символ пробелом
- fprintf - функция, используемая для записи в файл вывода
- fclose - функция, используемая для закрытия файла
- perror - функция, используемая для вывода сообщения об ошибке Основной цикл программы считывает строки из входного файла и записывает их в выходной файл, обрезая строки до заданной ширины. Если входной файл содержит символы новой строки ('\n'), они сохраняются в выходном файле. Если выходной файл не stdout, он закрывается после записи всех строк.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д