online compiler and debugger for c/c++

code. compile. run. debug. share.
Source Code   
Language
/* ================================================================= Step 3 (Solution see Step 4) ================================================================= */ #include "do_averages.h" #include <sstream> // std::istringstream // std::ostringstream #ifndef TEST int main() { do_averages(); } #else #include "pxt.h" int main() { { //////////////////////////////////////////////////////////// std::istringstream input{ "1 5 7" "\n" "1.5 7" "\n" "15.7" "\n" }; std::ostringstream output{}; PX(do_averages(&input, &output), output.str()) >>= "4.33333" "\n" "4.25" "\n" "15.7" "\n"; } //////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////// std::istringstream input{"\n"}; std::ostringstream output{}; PX(do_averages(&input, &output), output.str()) == ""; } //////////////////////////////////////////////////////////// { //////////////////////////////////////////////////////////// std::istringstream input{ "1 5 7" "\n" "1 S 7" "\n" "15.7" "\n" }; std::ostringstream output{}; PX(do_averages(&input, &output), output.str()) >>= "4.33333" "\n" "1" "\n" "15.7" "\n"; } //////////////////////////////////////////////////////////// } #endif
# TODO STEP 3 - Examine the file structure of the two implementation files (aka. translation units) `main.cpp` and `do_averages.cpp` and the single header file `averages.h`). together - ¨Understand that in `main.cpp` there are two different `main` functions (though both cannot exist at the same time): - one is for interactive testing (as used in the previous step); - the other contributes a "TDD approach" (TDD = "Test Driven Development") which means the function `do_averages` is called with prepared input and its output is checked against expectations. - Which `main` program gets compiled depends on whether the macro `TEST` is defined during on compilation. - you may add its definition directly to the source code in file `main.cpp` with a line near the beginning:\ `#define TEST` - alternatively, if `g++` or `clang++` is used for compilation that macro can be defined without changing the source code in `main.cpp` by using the command line option `-DTEST`. Currently `do_averages` has default arguments, which allows to call it without any arguments from the `main` function for interactive use. - Remove the default arguments and add an overload instead, so that call without arguments in `main` for interactive use can stay the same. NOTE: Do not invest time into examining the files `pxt.h` and `pxt.cpp`.\ **YANETUT (You Are Not Expected To Understand This.)**\ Their content is "advance stuff" when it comes to *how it is implemented* but still meant to be *easy to use* for "test driven development". The only point to make sure is to hand over the names of all implementation files including `pxt.cpp` to the compile command by using `*.cpp`. ----------------------------------------------------------------- TODO (optional - meant for further self-study only): - Add some more tests, especially for the border cases like: - completely empty input - just a single number - empty line between non-empty lines - non-numeric input in the middle - non numeric input at the start - Build "test groups" by putting related tests in a single function, then from `main` just call theses functions. (The intent here is that now each test group can be easily enabled or disabled by putting a '//'-comment in front of such a function call.)
#include <iostream> void do_averages(std::istream* in = &std::cin, std::ostream* out = &std::cout);
#ifndef PXT_header_only #include "pxt.h" #endif #include <iostream> namespace PXT_namespace { std::ostream& PXT_class::out_stream{PXT_ostream}; PXT_class::Result PXT_class::counter{0, 0}; PXT_class::Result::~Result() { if (failed > 0) { PXT_class::out_stream << "** " << failed << " of " << total << " tests failed **" << std::endl; } else if (total > 0) { PXT_class::out_stream << "** ALL " << total << " TESTS PASSED **" << std::endl; } } std::ostream& PXT_class::source_location() const { return out_stream << file_ << ' ' << '[' << func_ << ':' << line_ << ']' << ' ' << texpr_; } void PXT_class::plain_output() { source_location() << " == " << streamed_result.str() << std::endl; } void PXT_class::two_line_compare() { done_ = true; ++counter.total; if (streamed_result.str() != expected_result.str()) { ++counter.failed; source_location() << '\n' << " = received: " << streamed_result.str() << '\n' << " ! expected: " << expected_result.str() << std::endl; } } void PXT_class::multi_line_compare() { std::string streamed_line{}; std::string expected_line{}; std::ostringstream common{}; while (std::getline(streamed_result, streamed_line), (expected_result >> std::ws), std::getline(expected_result, expected_line), !streamed_result.eof() && !expected_result.eof() && (streamed_line == expected_line)) { common << " = " << expected_line << '\n'; } done_ = true; ++counter.total; if (streamed_result.eof() && expected_result.eof()) return; // no difference ++counter.failed; if (streamed_result.eof()) { // less streamed than expected source_location() << '\n' << common.str() << " + expected: " << expected_line << std::endl; return; } if (expected_result.eof()) { // less expected than streamed source_location() << '\n' << common.str() << " + received: " << streamed_line << std::endl; return; } source_location() << '\n' // difference in streamed to expected << common.str() << " ~ received: " << streamed_line << '\n' << " ~ expected: " << expected_line << std::endl; } } // namespace
#include "do_averages.h" #include <iostream> // std::cin // std::cout // std::istream // std::ostream #include <sstream> // std::istringstream // std::ostringstream #include <string> // std::getline // std::string void do_averages(std::istream* in, std::ostream* out) { std::string line; while (std::getline(*in, line)) { float value = 0.0f; float sum = 0.0f; int count = 0; std::istringstream iss{line}; while (iss >> value) { sum += value; ++count; } if (count == 0) return; *out << sum/count << std::endl; } }
#ifndef PXT_off #ifndef PXT_ostream #define PXT_ostream std::cout #endif #define PX(...)\ PXT_namespace::PXT_class{__func__, __FILE__, __LINE__, #__VA_ARGS__, (__VA_ARGS__)} #if defined(PXT_HAVE_BOOST_TYPEINDEX)\ || defined(__has_include) && __has_include(<boost/type_index.hpp>) #include <boost/type_index.hpp> #define PT(...)\ PXT_namespace::PXT_helper(__func__, __FILE__, __LINE__, #__VA_ARGS__,\ boost::typeindex::type_id_with_cvr<__VA_ARGS__>()) #endif #if !defined(PX)\ || !defined(PT) struct PXT_dummy{ template<typename T> void operator==(T const&) const {} template<typename T> void operator*=(T const&) const {} template<typename T> void operator>>=(T const&) const {} template<typename T> void operator%=(T const&) const {} }; #if !defined(PX) #define PX(...) PXT_dummy{} #endif #if !defined(PT) #define PT(...) PXT_dummy{} #endif #endif #include <sstream> #include <iostream> namespace PXT_namespace { class PXT_class { bool done_{}; char const* func_; char const* file_; int const line_{}; char const* texpr_; std::stringstream streamed_result{}; std::stringstream expected_result{}; std::ostream& source_location() const; void plain_output(); void two_line_compare(); void multi_line_compare(); void glob_pattern_compare(); struct Result { unsigned long long total; unsigned long long failed; ~Result(); }; static Result counter; public: static std::ostream& out_stream; static bool ignore_expecations; template<typename T> PXT_class(char const* func, char const* file, int line, char const* texpr, T const& expr) : func_{func}, file_{file}, line_{line}, texpr_{texpr} { streamed_result.copyfmt(out_stream); streamed_result << expr; } ~PXT_class() { if (not done_) plain_output(); } template<typename T> void operator==(T const& expr) { expected_result.copyfmt(streamed_result); expected_result << expr; two_line_compare(); } void operator>>=(std::string lines) { expected_result << lines; multi_line_compare(); } void operator*=(std::string smatch) { glob_pattern_compare(); } }; } // namespace #ifdef PXT_header_only #include "pxt.cpp" #endif #endif

Compiling Program...

Command line arguments:
Standard Input: Interactive Console Text
×

                

                

Program is not being debugged. Click "Debug" button to start program in debug mode.

#FunctionFile:Line
VariableValue
RegisterValue
ExpressionValue