Скопировать содержимое, ограничив длину строки 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, он закрывается после записи всех строк.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д