Скопировать содержимое, ограничив длину строки N символами - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Всем доброго времени суток, нужна помощь с задачей: "Скопировать содержимое текстового файла, ограничив длину строки N символами. Слова, не помещающиеся в заданную строку не копировать." Поработав с программами, найденными в интернете получил две разные программы: 1)
Листинг программы
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #define LEN_STR 1024
  5. #define N 5
  6. char seps[10] = " ,.!?:;'\n";
  7. char* text;
  8. char* temp;
  9. FILE* source;
  10. FILE* target;
  11. void main(void)
  12. {
  13. source = fopen("1.txt", "rt");
  14. target = fopen("2.txt", "wt");
  15. text = (char*)calloc(LEN_STR, 1);
  16. temp = (char*)calloc(LEN_STR, 1);
  17. while (!feof(source))
  18. {
  19. fgets(text, LEN_STR, source);
  20. strncpy(temp, text, N);
  21. if (strlen(text) > N)
  22. {
  23. temp[N] = '\n';
  24. temp[N + 1] = 0;
  25. }
  26. fputs(temp, target);
  27. }
  28. fclose(source);
  29. fclose(target);
  30. free(text);
  31. free(temp);
  32. }
2)
Листинг программы
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #define MAXLEN 4 //Макс. длина строки
  5. int main(void)
  6. {
  7. char c=0; //Хранится символ из входного файла, вспомогательная переменная
  8. char String[MAXLEN + 1];
  9. char *pathFileInput=(char*)calloc(20, sizeof(char));
  10. char *pathFileOutput=(char*)calloc(20, sizeof(char));
  11. FILE *fileInput; //Файловая переменная для входного файла
  12. FILE *fileOutput; //Файловая переменная для выходного файла
  13. fileInput=fopen("1.txt", "rt");
  14. fileOutput= fopen("2.txt", "wt");
  15. while(c!=EOF)
  16. {
  17. fgets(String,MAXLEN + 1,fileInput);
  18. fputs(String,fileOutput);
  19. fputc('\n', fileOutput);
  20. while (c != '\n' && c != EOF)
  21. c = fgetc(fileInput);
  22.  
  23. if (c!=EOF) //Если это не признак конца файла, c = пробел (или любой другой неслужебный символ
  24. c=' '; //иначе мы застрянем во вложенном while на след. итерации
  25. }
  26. free(pathFileInput);
  27. free(pathFileOutput);
  28. fclose (fileInput);
  29. fclose(fileOutput);
  30. return 0;
  31. }
И всё бы ничего, но обе программы просто обрывают слова на середине, если эти слова не влезают в длину, а нужно, чтобы если слово не помещалось, то оно целиком и полностью удалялось. Посидев, пораскинув мозгами прикинул следующую схему: 1) Копируем текстовый документ 1.txt, работаем с каждой строкой по очереди; 2) В общем цикле для работы с каждой строкой: Разбивать строку на слова, слова заносить в массив, а дальше в цикле сравнивать длину i первых слов в массиве (с пробелами) с числом N. Если i < N, то идти дальше. Если i > N, то если кол-во слов больше одного, то записывать [i-1] слов из массива в строку и переходить к следующей строке. Ну или как-то так. На словах, как говорится, Лев Толстой... А время поджимает. Попробовав реализовать, понял, что проблема в моих знаниях и опыте. Буду очень благодарен, если доделаете мою программу или предложите свой вариант. Мои наработки:
Листинг программы
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #define LEN_STR 1024
  5. #define N 5
  6. char seps[10] = " ,.!?:;'\n";
  7. char* text;
  8. char* temp;
  9. char* word;
  10. FILE* source;
  11. FILE* target;
  12. char* data[100];
  13. void main(void)
  14. {
  15. source = fopen("1.txt", "rt");
  16. target = fopen("2.txt", "wt");
  17. text = (char*)calloc(LEN_STR, 1);
  18. temp = (char*)calloc(LEN_STR, 1);
  19. while (!feof(source))
  20. {
  21. fgets(text, LEN_STR, source);
  22. //Заимствуем код из программы, удаляющей слова, больше определённого размера
  23. //last = temp;
  24. //word = strtok(temp, seps);
  25. //while (word)
  26. //{
  27. // strncat(res, text + (last - temp), word - last);
  28. // if (strlen(word) <= N)
  29. // strcat(res, word);
  30. //
  31. // last = word + strlen(word);
  32. // word = strtok(NULL, seps);
  33. //}
  34. //strcat(res, text + (last - temp));
  35. word = strtok(temp, seps);
  36. while (word)
  37. {
  38. data = data + word;
  39. if (strlen(data) > N)
  40. {
  41. temp[N] = '\n';
  42. temp[N + 1] = 0;
  43. }
  44. fputs(temp, target);
  45. word = strtok(NULL, seps);
  46. }
  47. strcat(res, text + (last - temp));
  48. }
  49. fclose(source);
  50. fclose(target);
  51. free(text);
  52. free(temp);
  53. }

Решение задачи: «Скопировать содержимое, ограничив длину строки N символами»

textual
Листинг программы
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <ctype.h>
  4. #include <stdlib.h>
  5.  
  6. #define DEFAULT_OUTPUT_WIDTH (80)
  7. #define PROGRAM_NAME argv[0]
  8. #define INPUT_FILE_NAME argv[1]
  9. #define OUTPUT_FILE_NAME argv[2]
  10. #define OUTPUT_WIDTH argv[3]
  11. #define INPUT_BUFFER_SIZE (2048)
  12.  
  13. int main(int argc, char ** argv) {
  14.     FILE * fIn, * fOut;
  15.     char * bufIn, * bufOut, * posPtr;
  16.     size_t inpLen, outLen, tmpLen;
  17.    
  18.     if ( argc < 2 ) {
  19.         fprintf(stderr, "USAGE: %s input_file [output_file [width]]\n", PROGRAM_NAME);
  20.         exit(EXIT_FAILURE);
  21.     }
  22.    
  23.     if ( argc == 4 ) {
  24.         outLen = atoi(OUTPUT_WIDTH);
  25.         if ( outLen < 1 || outLen >= INPUT_BUFFER_SIZE ) {
  26.             fprintf(stderr, "%s: wrong parameter to output width - %lu\n", PROGRAM_NAME, outLen);
  27.             exit(EXIT_FAILURE);
  28.         }
  29.     }
  30.     else
  31.         outLen = DEFAULT_OUTPUT_WIDTH;
  32.    
  33.     if ( ! ( bufIn = malloc(INPUT_BUFFER_SIZE) ) ) {
  34.         perror("malloc");
  35.         exit(EXIT_FAILURE);
  36.     }
  37.    
  38.     if ( ! ( bufOut = malloc(outLen + 2) ) ) {
  39.         free(bufIn);
  40.         perror("malloc");
  41.         exit(EXIT_FAILURE);
  42.     }
  43.    
  44.     if ( ! ( fIn = fopen(INPUT_FILE_NAME, "r") ) ) {
  45.         fprintf(stderr, "%s: can't open file %s for input!\n", PROGRAM_NAME, INPUT_FILE_NAME);
  46.         free(bufIn);
  47.         free(bufOut);
  48.         exit(EXIT_FAILURE);
  49.     }
  50.    
  51.     if ( argc == 2 )
  52.         fOut = stdout;
  53.     else {
  54.         if ( ! ( fOut = fopen(OUTPUT_FILE_NAME, "w") ) ) {
  55.             fprintf(stderr, "%s: can't open file %s for output!\n", PROGRAM_NAME, OUTPUT_FILE_NAME);
  56.             fclose(fIn);
  57.             free(bufIn);
  58.             free(bufOut);
  59.             exit(EXIT_FAILURE);
  60.         }
  61.     }
  62.    
  63.     while ( fgets(bufIn, INPUT_BUFFER_SIZE, fIn) ) {
  64.         while ( ( inpLen = strlen(bufIn) ) > outLen ) {
  65.             for ( posPtr = bufIn + outLen - 1; posPtr >= bufIn && ! isspace(*posPtr); --posPtr )
  66.                 ;
  67.             if ( posPtr < bufIn ) {
  68.                 memcpy(bufOut, bufIn, outLen);
  69.                 bufOut[outLen] = '\n';
  70.                 bufOut[outLen + 1] = '\0';
  71.                 if ( fprintf(fOut, "%s", bufOut) == EOF ) {
  72.                     fprintf(stderr, "%s: can't write to output file!\n", PROGRAM_NAME);
  73.                     if ( fclose(fIn) )
  74.                         perror("While close input file");
  75.                     if ( fclose(fOut) )
  76.                         perror("While close output file");
  77.                     free(bufIn);
  78.                     free(bufOut);
  79.                     exit(EXIT_FAILURE);
  80.                 }
  81.                 memmove(bufIn, bufIn + outLen, strlen(bufIn + outLen) + 1);
  82.             }
  83.             else {
  84.                 tmpLen = posPtr - bufIn;
  85.                 memcpy(bufOut, bufIn, tmpLen);
  86.                 bufOut[tmpLen] = '\n';
  87.                 bufOut[tmpLen + 1] = '\0';
  88.                 if ( fprintf(fOut, "%s", bufOut) == EOF ) {
  89.                     fprintf(stderr, "%s: can't write to output file!\n", PROGRAM_NAME);
  90.                     if ( fclose(fIn) )
  91.                         perror("While close input file");
  92.                     if ( fclose(fOut) )
  93.                         perror("While close output file");
  94.                     free(bufIn);
  95.                     free(bufOut);
  96.                     exit(EXIT_FAILURE);
  97.                 }
  98.                 memmove(bufIn, bufIn + tmpLen + 1, strlen(bufIn + tmpLen));
  99.             }
  100.         }
  101.         if ( inpLen ) {
  102.             if ( fprintf(fOut, "%s", bufIn) == EOF ) {
  103.                 fprintf(stderr, "%s: can't write to output file!\n", PROGRAM_NAME);
  104.                 if ( fclose(fIn) )
  105.                     perror("While close input file");
  106.                 if ( fclose(fOut) )
  107.                     perror("While close output file");
  108.                 free(bufIn);
  109.                 free(bufOut);
  110.                 exit(EXIT_FAILURE);
  111.             }
  112.         }
  113.     }
  114.    
  115.     if ( ferror(fIn) ) {
  116.         fprintf(stderr, "%s: error while reading input file!\n", PROGRAM_NAME);
  117.         if ( fclose(fIn) )
  118.             perror("While close input file");
  119.         if ( fclose(fOut) )
  120.             perror("While close output file");
  121.         free(bufIn);
  122.         free(bufOut);
  123.         exit(EXIT_FAILURE);
  124.     }
  125.    
  126.     if ( fclose(fIn) )
  127.         perror("While close input file");
  128.     if ( fOut != stdout && fclose(fOut) )
  129.         perror("While close output file");
  130.    
  131.     free(bufIn);
  132.     free(bufOut);
  133.    
  134.     exit(EXIT_SUCCESS);
  135. }

Объяснение кода листинга программы

Этот код предназначен для копирования содержимого из одного файла в другой с ограничением на количество символов в каждой строке. Он использует стандартные библиотеки C и может быть скомпилирован с помощью любого компилятора C. Список переменных и их значений:

  1. argc - количество аргументов в командной строке (обычно 2 или 4)
  2. argv - массив строк, содержащих параметры командной строки
  3. PROGRAM_NAME - имя программы (обычно имя исполняемого файла)
  4. INPUT_FILE_NAME - имя входного файла
  5. OUTPUT_FILE_NAME - имя выходного файла (если не указано, то это stdout)
  6. OUTPUT_WIDTH - ширина вывода (если не указано, то это 80)
  7. DEFAULT_OUTPUT_WIDTH - значение по умолчанию для OUTPUT_WIDTH, равное 80
  8. INPUT_BUFFER_SIZE - размер буфера ввода, равный 2048
  9. fIn - файловый указатель на входной файл
  10. fOut - файловый указатель на выходной файл (может быть stdout)
  11. bufIn - указатель на буфер ввода
  12. bufOut - указатель на буфер вывода
  13. inpLen - длина строки в буфере ввода
  14. outLen - длина строки в буфере вывода
  15. tmpLen - временная переменная для хранения длины строки
  16. posPtr - указатель на текущую позицию в строке
  17. isspace - функция, проверяющая, является ли символ пробелом
  18. fprintf - функция, используемая для записи в файл вывода
  19. fclose - функция, используемая для закрытия файла
  20. perror - функция, используемая для вывода сообщения об ошибке Основной цикл программы считывает строки из входного файла и записывает их в выходной файл, обрезая строки до заданной ширины. Если входной файл содержит символы новой строки ('\n'), они сохраняются в выходном файле. Если выходной файл не stdout, он закрывается после записи всех строк.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

8   голосов , оценка 4.25 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы