Files
CS-LABS/mine/lab_1/.old/12_first_symbols_to_spaces.cpp
2025-12-10 16:50:28 +07:00

108 lines
3.1 KiB
C++

#include <iostream>
#include <fstream>
#include <string>
#include <sys/stat.h>
#include <cerrno>
#include <cstdlib>
#include <climits>
static bool file_exists(const std::string &path) {
struct stat st{};
return ::stat(path.c_str(), &st) == 0; // stat success => exists [web:59]
}
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 void print_usage(const char* prog) {
std::cerr << "Usage: " << prog << " <input_file> <replace_count>\n"; // positional args [web:59]
}
static bool parse_ll(const char* s, long long& out) {
if (!s || !*s) return false;
errno = 0;
char* end = nullptr;
long long v = std::strtoll(s, &end, 10); // use endptr and errno [web:59]
if (errno == ERANGE) return false;
if (end == s || *end != '\0') return false;
out = v;
return true;
}
int main(int argc, char* argv[]) {
if (argc != 3) {
print_usage(argv[0]);
return -1;
}
std::string in_path = argv[1];
long long replace_limit = 0;
if (!parse_ll(argv[2], replace_limit) || replace_limit < 0) {
std::cerr << "Error: replace_count must be a non-negative integer.\n";
return -1;
}
if (!file_exists(in_path)) {
std::cerr << "Error: input file does not exist.\n";
return -1;
}
std::ifstream in(in_path);
if (!in) {
std::cerr << "Error: cannot open input file.\n";
return -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;
}
long long performed = 0;
std::string line;
while (performed < replace_limit && std::getline(in, line)) { // stop early when limit hit [web:59]
if (!line.empty()) {
char first = line.front();
for (char &c: line) {
if (c == first && c != ' ') {
c = ' ';
++performed;
if (performed >= replace_limit) break; // cap reached [web:44]
}
}
}
out << line;
if (!in.eof()) out << '\n';
if (!out) {
std::cerr << "Error: write error.\n";
return -1;
}
}
// If limit reached mid-file, copy the rest unchanged
if (performed >= replace_limit) { // stream may be mid-line or between lines [web:59]
// Write remaining lines as-is
if (!in.eof()) {
// Flush any remaining part of current line already written; then dump rest
std::string rest;
while (std::getline(in, rest)) {
out << rest;
if (!in.eof()) out << '\n';
if (!out) {
std::cerr << "Error: write error.\n";
return -1;
}
}
}
}
std::cout << performed << std::endl; // print actual replacements up to limit [web:59]
return 0; // success [web:59]
}