diff --git a/others/kirill`s/lab1/compile.sh b/others/kirill`s/lab1/compile.sh deleted file mode 100755 index f71c378..0000000 --- a/others/kirill`s/lab1/compile.sh +++ /dev/null @@ -1 +0,0 @@ -g++ task18.cpp -o task18 diff --git a/others/kirill`s/lab1/file.in b/others/kirill`s/lab1/file.in deleted file mode 100644 index 67420cc..0000000 --- a/others/kirill`s/lab1/file.in +++ /dev/null @@ -1,11 +0,0 @@ -abcdef -abcdefg -abcdefghij -abc def -x -12 -123 - (three spaces) -abc -ab cs s dds -\tabcde\tf \ No newline at end of file diff --git a/others/kirill`s/lab1/in.txt b/others/kirill`s/lab1/in.txt new file mode 100644 index 0000000..f2b6b71 --- /dev/null +++ b/others/kirill`s/lab1/in.txt @@ -0,0 +1,2 @@ +123456 +123456 \ No newline at end of file diff --git a/others/kirill`s/lab1/task18.cpp b/others/kirill`s/lab1/task18.cpp index 9b71547..13839d7 100644 --- a/others/kirill`s/lab1/task18.cpp +++ b/others/kirill`s/lab1/task18.cpp @@ -1,96 +1,123 @@ -#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_var_thirds_line \n" + "Replace every third byte in each line with a space; counter resets after each newline.\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 perms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; /* 0666 */ + int out_fd = open(out_path, O_CREAT | O_WRONLY | O_TRUNC, perms); + 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; + long long total = 0; + long long col = 0; /* position in current line starting from 1 */ + int replacing_enabled = 1; - while (std::getline(in, line)) { - if (!line.empty() && replacements < target) { - for (std::size_t idx = 0; idx < line.size() && replacements < target; ++idx) { - std::size_t pos1 = idx + 1; - if ((pos1 % 3) == 0) { - if (line[idx] != ' ') { - line[idx] = ' '; - ++replacements; + 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 (c == '\n') { + /* newline is written as-is and resets counter */ + 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++] = '\n'; + col = 0; + continue; + } + + col++; /* advance within the current line */ + + unsigned char outc = c; + if (replacing_enabled && (col % 3 == 0)) { + if (total < cap) { + outc = ' '; + total++; + if (total == cap) replacing_enabled = 0; + } 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; } - } - out << line; - if (!in.eof()) out << '\n'; - if (!out) { - std::cerr << "Error: write error.\n"; - return -1; + } 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 (!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); + if (m > 0) (void) write(STDOUT_FILENO, res, (size_t) m); - std::cout << replacements << std::endl; - return 0; + int exit_code = (int) (total & 0xFF); + return exit_code; } diff --git a/others/vlad`s/lab1/in.txt b/others/vlad`s/lab1/in.txt index 69e5568..50fee4e 100644 --- a/others/vlad`s/lab1/in.txt +++ b/others/vlad`s/lab1/in.txt @@ -1 +1,2 @@ -aaaaabababbabababaaabbbbabababbbaabbaabbabb \ No newline at end of file +aaaaaa +aaaaaa \ No newline at end of file