diff --git a/others/vlad`s/lab1/compile.sh b/others/vlad`s/lab1/compile.sh deleted file mode 100755 index 9b9046f..0000000 --- a/others/vlad`s/lab1/compile.sh +++ /dev/null @@ -1 +0,0 @@ -g++ task11.cpp -o task11 diff --git a/others/vlad`s/lab1/file.in b/others/vlad`s/lab1/file.in deleted file mode 100644 index a3ea8a7..0000000 --- a/others/vlad`s/lab1/file.in +++ /dev/null @@ -1,13 +0,0 @@ -aabbcc -bookkeeper -Mississippi -x -aa -aba -aaa -baaa -aaab -abba -1222333 - (four spaces) ---==== diff --git a/others/vlad`s/lab1/in.txt b/others/vlad`s/lab1/in.txt new file mode 100644 index 0000000..69e5568 --- /dev/null +++ b/others/vlad`s/lab1/in.txt @@ -0,0 +1 @@ +aaaaabababbabababaaabbbbabababbbaabbaabbabb \ No newline at end of file diff --git a/others/vlad`s/lab1/task11.cpp b/others/vlad`s/lab1/task11.cpp index b52a420..f2512be 100644 --- a/others/vlad`s/lab1/task11.cpp +++ b/others/vlad`s/lab1/task11.cpp @@ -1,95 +1,170 @@ -#include -#include -#include +#include #include -#include -#include +#include +#include +#include +#include +#include -static bool file_exists(const std::string &path) { - struct stat st{}; - return ::stat(path.c_str(), &st) == 0; +#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 std::string make_out_name(const std::string &in) { - std::size_t pos = in.find_last_of('.'); - if (pos == std::string::npos) return in + ".out"; - return in.substr(0, pos) + ".out"; -} - -static bool parse_nonneg_ll(const char *s, long long &out) { - if (!s || *s == '\0') return false; - char *end = nullptr; +static long long parse_ll(const char *s) { + char *end = NULL; errno = 0; - long long v = std::strtoll(s, &end, 10); - if (errno != 0 || end == s || *end != '\0') return false; - if (v < 0) return false; - out = v; - return true; + 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 != 3) { - std::cerr << "Usage: " << argv[0] << " input_file replace_count\n"; + if (argc != 4) { + const char *usage = + "Usage: lab1_var11 \n" + "Variant 11: for every pair of identical consecutive characters, replace the second with a space.\n" + " Stop after replacements globally.\n"; + (void) write(STDERR_FILENO, usage, strlen(usage)); return -1; } - std::string in_path = argv[1]; - long long target = 0; - if (!parse_nonneg_ll(argv[2], target)) { - std::cerr << "Usage: " << argv[0] << " input_file replace_count\n"; - 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); } - if (!file_exists(in_path)) { - std::cerr << "Error: input file does not exist.\n"; - return -1; + int in_fd = open(in_path, O_RDONLY); + if (in_fd < 0) { + die_perror("open input failed", in_path, -1); } - std::ifstream in(in_path); - if (!in) { - std::cerr << "Error: cannot open input file.\n"; - return -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); } - std::string out_path = make_out_name(in_path); - std::ofstream out(out_path); - if (!out) { - std::cerr << "Error: cannot create output file.\n"; - return -1; - } + char rbuf[RBUFSZ]; + char wbuf[WBUFSZ]; + size_t wlen = 0; - long long replacements = 0; - std::string line; + /* state */ + long long total_replacements = 0; + int replacing_enabled = 1; - while (std::getline(in, line)) { - if (!line.empty() && replacements < target) { - for (std::size_t i = 1; i < line.size() && replacements < target; ++i) { - if (line[i] == line[i - 1]) { - if (line[i] != ' ') { - line[i] = ' '; - ++replacements; + int have_prev = 0; + unsigned char prev = 0; + + 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 (!have_prev) { + /* buffer first byte of a potential pair */ + prev = c; + have_prev = 1; + continue; + } + + if (c == prev) { + /* non-overlapping pair found: output prev, then second element possibly replaced */ + unsigned char out1 = prev; + unsigned char out2 = c; + + if (replacing_enabled && total_replacements < cap) { + out2 = ' '; + total_replacements++; + if (total_replacements == cap) { + replacing_enabled = 0; + } + } else { + replacing_enabled = 0; } + + /* write out1 */ + 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) out1; + + /* write out2 */ + 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) out2; + + /* consume pair: reset have_prev so next byte starts a new potential pair */ + have_prev = 0; + } else { + /* no pair: output prev, shift window to c */ + 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) prev; + + prev = c; + have_prev = 1; } } - } - out << line; - if (!in.eof()) out << '\n'; - if (!out) { - std::cerr << "Error: write error.\n"; - return -1; + } else if (n == 0) { + /* flush any pending single prev */ + if (have_prev) { + 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) prev; + have_prev = 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 (!in.eof() && in.fail()) { - std::cerr << "Error: read error.\n"; - return -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); } - if (replacements != target) { - std::cerr << "Error: could not perform exactly requested replacements.\n"; - return -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); } - std::cout << replacements << std::endl; - return 0; + int exit_code = (int) (total_replacements & 0xFF); + return exit_code; }