diff options
Diffstat (limited to 'challenge-098/paulo-custodio/cpp/ch-1.cpp')
| -rw-r--r-- | challenge-098/paulo-custodio/cpp/ch-1.cpp | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/challenge-098/paulo-custodio/cpp/ch-1.cpp b/challenge-098/paulo-custodio/cpp/ch-1.cpp new file mode 100644 index 0000000000..0d3f5c0cc3 --- /dev/null +++ b/challenge-098/paulo-custodio/cpp/ch-1.cpp @@ -0,0 +1,76 @@ +/* +Challenge 098 + +TASK #1 › Read N-characters +Submitted by: Mohammad S Anwar +You are given file $FILE. + +Create subroutine readN($FILE, $number) returns the first n-characters and +moves the pointer to the (n+1)th character. + +Example: +Input: Suppose the file (input.txt) contains "1234567890" +Output: + print readN("input.txt", 4); # returns "1234" + print readN("input.txt", 4); # returns "5678" + print readN("input.txt", 4); # returns "90" +*/ + +#include <algorithm> +#include <array> +#include <iostream> +#include <fstream> +#include <string> +#include <cassert> +#include <cstring> + +// store list of open files +class Files { +public: + std::string readN(const std::string filename, int n) { + std::ifstream& ifs = add_file(filename); + char* buffer = new char[n + 1]; + memset(buffer, 0, n + 1); + ifs.read(buffer, n); + auto text = std::string(buffer); + delete[] buffer; + return text; + } + +private: + // store std::ifstream in a pre-aloocated array as storing pointers to + // std::ifstream in an unordered_map was causing a heap corruption in + // GCC - probably a compiler/stdlib bug + static const int MAX_FILES = 20; + std::array<std::ifstream, MAX_FILES> files; + std::array<std::string, MAX_FILES> filenames; + size_t num_files{ 0 }; + + std::ifstream& add_file(const std::string filename) { + auto end = filenames.begin() + num_files; + auto found = std::find(filenames.begin(), end, filename); + if (found != end) { // found in filename + size_t i = std::distance(filenames.begin(), found); + return files[i]; + } + else { // not found, must create new entry + if (num_files >= MAX_FILES) { + std::cerr << "too many files" << std::endl; + exit(EXIT_FAILURE); + } + filenames[num_files] = filename; + files[num_files].open(filename); + if (!files[num_files].is_open()) { + std::cerr << "open file " << filename << " failed" << std::endl; + exit(EXIT_FAILURE); + } + return files[num_files++]; + } + } +}; + +int main(int argc, char* argv[]) { + Files f; + for (int i = 1; i + 1 < argc; i += 2) + std::cout << f.readN(argv[i], atoi(argv[i + 1])) << std::endl; +} |
