From 0b2396e157bbe9618a409b670cb4099956726ae3 Mon Sep 17 00:00:00 2001 From: pajjilykk Date: Sat, 4 Oct 2025 19:08:29 +0700 Subject: [PATCH] lab1 v2 --- lab_1/in.txt | 5 ++ lab_1/task12.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 140 insertions(+) create mode 100644 lab_1/in.txt diff --git a/lab_1/in.txt b/lab_1/in.txt new file mode 100644 index 0000000..2d15f49 --- /dev/null +++ b/lab_1/in.txt @@ -0,0 +1,5 @@ +abbaabbaabbaabbaabbaabbaabbaabba +xyzx + .. +.. ./. +---- diff --git a/lab_1/task12.c b/lab_1/task12.c index e69de29..25a8091 100644 --- a/lab_1/task12.c +++ b/lab_1/task12.c @@ -0,0 +1,135 @@ +#include +#include +#include +#include +#include +#include +#include + +#define RBUFSZ 4096 +#define WBUFSZ 4096 + +static void die_perror(const char *what, const char *path, int exit_code) { + int saved = errno; + char msg[512]; + if (path) { + snprintf(msg, sizeof(msg), "%s: %s: %s\n", what, path, strerror(saved)); + } else { + snprintf(msg, sizeof(msg), "%s: %s\n", what, strerror(saved)); + } + (void) write(STDERR_FILENO, msg, strlen(msg)); + _exit(exit_code); +} + +static long long parse_ll(const char *s) { + char *end = NULL; + errno = 0; + long long v = strtoll(s, &end, 10); + if (errno != 0 || end == s || *end != '\0' || v < 0) { + errno = EINVAL; + return -1; + } + return v; +} + +int main(int argc, char *argv[]) { + if (argc != 4) { + const char *usage = + "Usage: lab1_var12 \n" + "Variant 12: per line, take the first character as key and replace its matches with spaces,\n" + " stopping after replacements globally.\n"; + (void) write(STDERR_FILENO, usage, strlen(usage)); + return -1; + } + + const char *in_path = argv[1]; + const char *out_path = argv[2]; + long long cap = parse_ll(argv[3]); + if (cap < 0) { + die_perror("invalid max_replacements", argv[3], -1); + } + + int in_fd = open(in_path, O_RDONLY); + if (in_fd < 0) { + die_perror("open input failed", in_path, -1); + } + + mode_t filePerms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; /* rw-rw-rw- */ + int out_fd = open(out_path, O_CREAT | O_WRONLY | O_TRUNC, filePerms); + if (out_fd < 0) { + die_perror("open output failed", out_path, -1); + } + + char rbuf[RBUFSZ]; + char wbuf[WBUFSZ]; + size_t wlen = 0; + + long long total_replacements = 0; + int at_line_start = 1; + unsigned char line_key = 0; + int replacing_enabled = 1; /* flips to 0 when cap reached */ + + for (;;) { + ssize_t n = read(in_fd, rbuf, sizeof(rbuf)); + if (n > 0) { + for (ssize_t i = 0; i < n; i++) { + unsigned char c = (unsigned char) rbuf[i]; + + if (at_line_start) { + line_key = c; + at_line_start = 0; + } + + unsigned char outc = c; + if (c == '\n') { + at_line_start = 1; + } else if (replacing_enabled && c == line_key) { + if (total_replacements < cap) { + outc = ' '; + total_replacements++; + if (total_replacements == cap) { + replacing_enabled = 0; /* hit the cap; from now on just copy */ + } + } else { + replacing_enabled = 0; + } + } + + if (wlen == sizeof(wbuf)) { + ssize_t wrote = write(out_fd, wbuf, wlen); + if (wrote < 0 || (size_t) wrote != wlen) { + die_perror("write failed", out_path, -1); + } + wlen = 0; + } + wbuf[wlen++] = (char) outc; + } + } else if (n == 0) { + if (wlen > 0) { + ssize_t wrote = write(out_fd, wbuf, wlen); + if (wrote < 0 || (size_t) wrote != wlen) { + die_perror("write failed", out_path, -1); + } + wlen = 0; + } + break; + } else { + die_perror("read failed", in_path, -1); + } + } + + if (close(in_fd) < 0) { + die_perror("close input failed", in_path, -1); + } + if (close(out_fd) < 0) { + die_perror("close output failed", out_path, -1); + } + + char res[64]; + int m = snprintf(res, sizeof(res), "%lld\n", total_replacements); + if (m > 0) { + (void) write(STDOUT_FILENO, res, (size_t) m); + } + + return 0; +}