Video Coming Soon...
38: tee
The tee command is a useful utility I use maybe 3 times a year, but when I do use it I'm glad it's around. It works kind of like a "tee joint" in a pipe. Your input comes into the tee command standard input, and then goes out to a file and the standard output again. It's used to save the results of a sequence commands to a file and also view them, but it can also be used to save an intermediary view of the commands.
You run tee like this:
cat somefile.txt | tee saveto.txt > stdouthere.txt
The last part > stdouthere.txt can be omitted to see the output of tee in your terminal.
The Challenge
For this challenge you'll need the std::ios_base::openmod documentation so you can support the -a option to tee. There's many way you can implement this option, but this clue will tell you how to do the simplest version. Other than that, you can probably start with cat and go from there, or start over and try to figure it out from nothing again.
The Code
My version of tee does implement the simplest way to do -a, but in Further Study I'll have you try a few other ways.
See my first version of tee
View Source file tee.cpp Only#include <iostream>
#include <fstream>
#include <string>
#include <fmt/core.h>
#include <unistd.h>
void dump_file(std::istream& in, std::ostream& out_file) {
std::string line;
while(in) {
getline(in, line);
line.append("\n", 1);
std::cout.write(line.c_str(), line.size());
out_file.write(line.c_str(), line.size());
}
}
int main(int argc, char* argv[]) {
int opt = 0;
auto open_mode = std::ios::trunc;
while((opt = getopt(argc, argv, "a")) != -1) {
switch(opt) {
case 'a':
open_mode = std::ios::app;
break;
default:
fmt::print("USAGE: tee -a file > otherfile");
return 1;
}
}
std::ofstream out_file{argv[optind], open_mode | std::ios::binary };
dump_file(std::cin, out_file);
}
The Discussion
Did you over think it? I can think of a few ways you may try to over-engineer tee:
- You try to store the whole input in a buffer, then write once to the file and output.
- You try to do some weird copy between the input and both outputs.
- You went crazy and made
-away too complicated.
One exercise I try sometimes is to take something really simple like tee and make it "Enterprise Grade." It's kind of a joke because usually software written for big business is terrible because it's sold to CEOs and CFOs who know nothing about good software. Usually Enterprise Grade software is over-engineered, extremely complicated, slow as molasses, and businesses love that. No idea why but most businesses love paying for junk they barely use.
So, if you over-engineered your solution don't worry. That just means you're on the path to becoming an "Enterprise Class Developer."
In all seriousness though, go back and make it simpler, then try making it way more complex. It's educational to do both on some projects and is a fun game to over-engineer something simple like tee.
Further Study
How many different ways can you over-engineer tee? Feel free to add additional options, use the most convoluted functions for everything, and even use multiple .cpp files for no reason.
Register for Learn C++ the Hard Way
Register to gain access to additional videos which demonstrate each exercise. Videos are priced to cover the cost of hosting.