aboutsummaryrefslogtreecommitdiffstats
path: root/6_1.c
diff options
context:
space:
mode:
Diffstat (limited to '6_1.c')
-rw-r--r--6_1.c209
1 files changed, 0 insertions, 209 deletions
diff --git a/6_1.c b/6_1.c
deleted file mode 100644
index 25c61b5..0000000
--- a/6_1.c
+++ /dev/null
@@ -1,209 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-
-#define SIZEOFBUF 1024
-#define reset(bufsz) bufsz = SIZEOFBUF
-
-// копирует n линий из файла in в файл out
-void copy_n_lines(char **buf, size_t *bufsz, FILE *in, FILE *out, int n) {
- for (int i = 0; i < n; ++i) {
- getline(buf, bufsz, in);
- fputs(*buf, out);
- }
-}
-
-// комирует первые n столбцов из фала in в out
-void copy_n_words(char **buf, size_t *bufsz, FILE *in, FILE *out, int n, char delim) {
- ssize_t cursz;
- for (int i = 0; i < n; ++i) {
- if ((cursz = getdelim(buf, bufsz, delim, in)) < 0) return;
- fputs(*buf, out);
- }
-}
-
-// пропускает первые n слов в файле in
-void skip_n_words(char **buf, size_t *bufsz, FILE *in, int n, char delim) {
- for (int i = 0; i < n; ++i)
- getdelim(buf, bufsz, delim, in);
-}
-
-// вариант 1
-void change_surnames(FILE *in, FILE *out) {
- char *buf = malloc(SIZEOFBUF);
- size_t bufsz = SIZEOFBUF;
- ssize_t cursz;
- // первые 2 строки такие же
- copy_n_lines(&buf, &bufsz, in, out, 2);
- while (!feof(in)) {
- // получаем первое слово
- if ((cursz = getdelim(&buf, &bufsz, '\t', in)) < 0) break;
- buf[cursz-1] = '\0'; // убираем '\t' в конце
- fprintf(out, "%s%c\t", buf, rand() % ('z'-'a'+1)+'a');
- // копируем оставшуюся линию
- if (getline(&buf, &bufsz, in) < 0) break;
- fputs(buf, out);
- }
- free(buf);
-}
-
-// вариант 2
-void change_birth_dates(FILE *in, FILE *out) {
- char *buf = malloc(SIZEOFBUF);
- size_t bufsz = SIZEOFBUF;
- // первые 2 строки должны быть такими же
- copy_n_lines(&buf, &bufsz, in, out, 2);
- while (!feof(in)) {
- // и первые 3 слова тоже
- copy_n_words(&buf, &bufsz, in, out, 3, '\t');
- // меняем дату :devil:
- if (getdelim(&buf, &bufsz, '\t', in) < 0) break;
- int bd = atoi(buf);
- if (!bd) break;
- fprintf(out, "%i\t", bd + rand()%11-5);
- // выписываем оставшуюся строку
- if (getline(&buf, &bufsz, in) < 0) break;
- fputs(buf, out);
- }
- free(buf);
-}
-
-// вариант 3
-void avg_score(FILE *in, FILE *out) {
- char *buf = malloc(SIZEOFBUF);
- size_t bufsz = SIZEOFBUF;
- size_t counter = 0;
- long marks[3] = {0};
- // первые 4 столбца
- skip_n_words(&buf, &bufsz, in, 4, '\t');
- // комируем оставшуюся линию
- copy_n_lines(&buf, &bufsz, in, out, 1);
- while (!feof(in)) {
- // первые 4 столбца не интересуют
- skip_n_words(&buf, &bufsz, in, 4, '\t');
- if (getline(&buf, &bufsz, in) < 0) break;
- // здесь и в цикле выделяем 3 числа и прибавляем их к
- // оценкам по правильному индексу
- // strotok, а не getdelim, потому что доходим до конца строки
- strtok(buf, "\t\n");
- int index = 0;
- do {
- int tmp = atoi(buf);
- if (!tmp) break;
- marks[index] += tmp;
- ++index;
- } while ((buf = strtok(NULL, "\t\n")));
- ++counter;
- }
- // выводим результат
- fprintf(out, "%lf\t%lf\t%lf\n",
- (double)marks[0] / counter,
- (double)marks[1] / counter,
- (double)marks[2] / counter);
- free(buf);
-}
-
-// вариант 4
-void switch_marks(FILE *in, FILE *out) {
- char *buf = malloc(SIZEOFBUF);
- size_t bufsz = SIZEOFBUF;
- // первые 2 линие такие же
- copy_n_lines(&buf, &bufsz, in, out, 2);
- while (!feof(in)) {
- copy_n_words(&buf, &bufsz, in, out, 4, '\t');
- if (getline(&buf, &bufsz, in) < 0) break;
- // здесь и в цикле выделяем 3 числа и изменяем их по заданию
- // strotok, а не getdelim, потому что доходим до конца строки
- strtok(buf, "\t\n");
- do {
- int tmp = atoi(buf);
- if (!tmp) break;
- fprintf(out, "%i\t", 5-tmp+2); // о неет, кто поменял все оценки...
- } while ((buf = strtok(NULL, "\t\n")));
- fputc('\n', out); // не забываем newline
- }
- free(buf);
-}
-
-// вариант 5
-void excellents(FILE *in, FILE *out) {
- char *buf = malloc(SIZEOFBUF);
- size_t bufsz = SIZEOFBUF;
- ssize_t cursz;
- // возьмём столбцы из оригинального файла и скопируем нужные
- copy_n_lines(&buf, &bufsz, in, out, 1);
- copy_n_words(&buf, &bufsz, in, out, 1, '\t');
- skip_n_words(&buf, &bufsz, in, 3, '\t');
- copy_n_lines(&buf, &bufsz, in, out, 1);
- while (!feof(in)) {
- if ((cursz = getdelim(&buf, &bufsz, '\t', in)) < 0) break;
- // сохраняем фамилию на потом;
- char *lname = malloc(sizeof (char) * cursz);
- char *marks = NULL; // понадобится позже
- strncpy(lname, buf, cursz);
- // пропускаем 3 колонки (имя, отчество, дата рождения)
- skip_n_words(&buf, &bufsz, in, 3, '\t');
- // сохраняем строку оценок
- if ((cursz = getline(&buf, &bufsz, in)) < 0) goto free; // чтобы не было утечек памяти
- marks = malloc(sizeof (char) * cursz);
- strncpy(marks, buf, cursz);
- // цикл, в котором считаем кол-во пятёрок
- int fives_count = 0;
- strtok(buf, "\t\n");
- do {
- int tmp = atoi(buf);
- if (!tmp) break;
- if (tmp == 5) ++fives_count;
- } while ((buf = strtok(NULL, "\t\n")));
- if (fives_count >= 2)
- fprintf(out, "%s%s", lname, marks);
-free:
- free(lname);
- free(marks);
- }
-}
-
-// массив функций для более простого выбора варианта
-void (*variants[5])(FILE *, FILE *) = {
- change_surnames,
- change_birth_dates,
- avg_score,
- switch_marks,
- excellents
-};
-
-int main(int argc, char *argv[]) {
- srand(0xB19B00B5);
-
- // стандартный цикл обработки аргументов argv
- if (argc != 6) {
- fprintf(stderr, "usage: \n" "%s -i INPUT -o OUTPUT variant\n", *argv);
- return 1;
- }
- const char *in, *out;
- int var = 0;
- for (int i = 0; i < argc; ++i) {
- if (!strcmp(argv[i], "-i"))
- in = argv[++i];
- else if (!strcmp(argv[i], "-o"))
- out = argv[++i];
- else
- var = atoi(argv[i]);
- }
- if (var < 1 || var > 5) {
- fprintf(stderr, "Неправильный вариант: %i\n", var);
- return 1;
- }
- // открытие файлов
- FILE *f_in = fopen(in, "r");
- FILE *f_out = fopen(out, "w+");
- if (!f_in || !f_out) {
- fprintf(stderr, "Не удалось открыть файл: %s\n", strerror(errno));
- return 1;
- }
- // сам вызов функции
- variants[--var](f_in, f_out);
- return 0;
-}
-