From da507ffc90bd6519321189dae69d81cfebc41a79 Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Wed, 21 Feb 2018 22:39:39 -0700 Subject: [PATCH] Avoid where possible to use std::ostringstream to generate filenames. To students, this seems like an unnecessary detour. This may have been useful in olden times, but we now have helper functions to convert numbers to text without having to create a std::ostringstream in user code, and we also have std::to_string(). Finally, this avoids the awkward idiom std::ostringstream filename; ... std::ofstream output (filename.str().c_str()); where we have to call .str().c_str(). Instead of this, just create the filename in place and be done with it. --- examples/step-13/step-13.cc | 15 ++++++--------- examples/step-14/step-14.cc | 32 ++++++++++---------------------- examples/step-16/step-16.cc | 10 +++------- examples/step-17/step-17.cc | 14 ++++---------- examples/step-21/step-21.cc | 19 +++++++++++-------- examples/step-22/step-22.cc | 14 +++++--------- examples/step-31/step-31.cc | 12 +++++------- examples/step-37/step-37.cc | 29 +++++++++++------------------ examples/step-44/step-44.cc | 9 +++++---- examples/step-45/step-45.cc | 13 +++++-------- examples/step-46/step-46.cc | 10 +++------- examples/step-5/step-5.cc | 30 +++++------------------------- examples/step-56/step-56.cc | 11 ++++------- examples/step-57/step-57.cc | 24 +++++++++++------------- 14 files changed, 88 insertions(+), 154 deletions(-) diff --git a/examples/step-13/step-13.cc b/examples/step-13/step-13.cc index eaedb0c335..ce656786eb 100644 --- a/examples/step-13/step-13.cc +++ b/examples/step-13/step-13.cc @@ -55,7 +55,6 @@ #include #include #include -#include // The last step is as in all previous programs: namespace Step13 @@ -392,13 +391,13 @@ namespace Step13 {} - // After the description above, the function generating the actual output + // Following the description above, the function generating the actual output // is now relatively straightforward. The only particularly interesting // feature over previous example programs is the use of the // DataOutBase::default_suffix function, returning the usual // suffix for files of a given format (e.g. ".eps" for encapsulated // postscript files, ".gnuplot" for Gnuplot files), and of the generic - // DataOut::write function with a second argument, which + // DataOut::write() function with a second argument, which internally // branches to the actual output functions for the different graphics // formats, based on the value of the format descriptor passed as second // argument. @@ -418,12 +417,10 @@ namespace Step13 data_out.add_data_vector (solution, "solution"); data_out.build_patches (); - std::ostringstream filename; - filename << output_name_base << "-" - << this->refinement_cycle - << data_out.default_suffix (output_format) - << std::ends; - std::ofstream out (filename.str().c_str()); + std::ofstream out (output_name_base + + "-" + + std::to_string(this->refinement_cycle) + + data_out.default_suffix (output_format)); data_out.write (out, output_format); } diff --git a/examples/step-14/step-14.cc b/examples/step-14/step-14.cc index 4b24969798..c79aa2ce07 100644 --- a/examples/step-14/step-14.cc +++ b/examples/step-14/step-14.cc @@ -54,7 +54,6 @@ #include #include #include -#include // The last step is as in all previous programs: namespace Step14 @@ -344,13 +343,10 @@ namespace Step14 GridOutput::operator () (const DoFHandler &dof_handler, const Vector &/*solution*/) const { - std::ostringstream filename; - filename << output_name_base << "-" - << this->refinement_cycle - << ".eps" - << std::ends; - - std::ofstream out (filename.str().c_str()); + std::ofstream out (output_name_base + + "-" + + std::to_string(this->refinement_cycle) + + ".eps"); GridOut().write_eps (dof_handler.get_triangulation(), out); } } @@ -802,13 +798,9 @@ namespace Step14 data_out.add_data_vector (this->solution, "solution"); data_out.build_patches (); - std::ostringstream filename; - filename << "solution-" - << this->refinement_cycle - << ".gnuplot" - << std::ends; - - std::ofstream out (filename.str().c_str()); + std::ofstream out ("solution-" + + std::to_string(this->refinement_cycle) + + ".gnuplot"); data_out.write (out, DataOutBase::gnuplot); } @@ -2260,13 +2252,9 @@ namespace Step14 data_out.build_patches (); - std::ostringstream filename; - filename << "solution-" - << this->refinement_cycle - << ".gnuplot" - << std::ends; - - std::ofstream out (filename.str().c_str()); + std::ofstream out ("solution-" + + std::to_string(this->refinement_cycle) + + ".gnuplot"); data_out.write (out, DataOutBase::gnuplot); } diff --git a/examples/step-16/step-16.cc b/examples/step-16/step-16.cc index 979ab861ac..f8ce6e61df 100644 --- a/examples/step-16/step-16.cc +++ b/examples/step-16/step-16.cc @@ -88,7 +88,6 @@ // This is C++: #include #include -#include using namespace dealii; @@ -591,12 +590,9 @@ namespace Step16 data_out.add_data_vector (solution, "solution"); data_out.build_patches (); - std::ostringstream filename; - filename << "solution-" - << cycle - << ".vtk"; - - std::ofstream output (filename.str().c_str()); + std::ofstream output ("solution-" + + std::to_string(cycle) + + ".vtk"); data_out.write_vtk (output); } diff --git a/examples/step-17/step-17.cc b/examples/step-17/step-17.cc index e5db696af9..6bacda5732 100644 --- a/examples/step-17/step-17.cc +++ b/examples/step-17/step-17.cc @@ -88,7 +88,6 @@ // And this is simply C++ again: #include #include -#include // The last step is as in all previous programs: namespace Step17 @@ -941,17 +940,12 @@ namespace Step17 // This being done, process zero goes ahead with setting up the // output file as in step-8, and attaching the (localized) - // solution vector to the output object. (The code to generate the - // output file name is stolen and slightly modified from step-5, - // since we expect that we can do a number of cycles greater than - // 10, which is the maximum of what the code in step-8 could - // handle.) + // solution vector to the output object. if (this_mpi_process == 0) { - std::ostringstream filename; - filename << "solution-" << cycle << ".vtk"; - - std::ofstream output (filename.str().c_str()); + std::ofstream output ("solution-" + + std::to_string(cycle) + + ".vtk"); DataOut data_out; data_out.attach_dof_handler (dof_handler); diff --git a/examples/step-21/step-21.cc b/examples/step-21/step-21.cc index 5854ee69c1..145a3ae3ef 100644 --- a/examples/step-21/step-21.cc +++ b/examples/step-21/step-21.cc @@ -59,7 +59,6 @@ #include #include -#include // In this program, we use a tensor-valued coefficient. Since it may have a // spatial dependence, we consider it a tensor-valued function. The following @@ -1086,7 +1085,14 @@ namespace Step21 // @sect4{TwoPhaseFlowProblem::output_results} // There is nothing surprising here. Since the program will do a lot of time - // steps, we create an output file only every fifth time step. + // steps, we create an output file only every fifth time step and skip all + // other time steps at the top of the file already. + // + // When creating file names for output close to the bottom of the function, + // we convert the number of the time step to a string representation that + // is padded by leading zeros to four digits. We do this because this way + // all output file names have the same length, and consequently sort well + // when creating a directory listing. template void TwoPhaseFlowProblem::output_results () const { @@ -1122,12 +1128,9 @@ namespace Step21 data_out.build_patches (degree+1); - std::ostringstream filename; - filename << "solution-" - << Utilities::int_to_string(timestep_number,4) - << ".vtk"; - - std::ofstream output (filename.str().c_str()); + std::ofstream output ("solution-" + + Utilities::int_to_string(timestep_number,4) + + ".vtk"); data_out.write_vtk (output); } diff --git a/examples/step-22/step-22.cc b/examples/step-22/step-22.cc index 20442d8c5b..6dec38d9aa 100644 --- a/examples/step-22/step-22.cc +++ b/examples/step-22/step-22.cc @@ -67,7 +67,6 @@ #include #include #include -#include // As in all programs, the namespace dealii is included: namespace Step22 @@ -845,9 +844,9 @@ namespace Step22 // DataComponentInterpretation namespace: as with the filename, // we create a vector in which the first dim components refer // to the velocities and are given the tag - // DataComponentInterpretation::component_is_part_of_vector; we + // DataComponentInterpretation::component_is_part_of_vector; we // finally push one tag - // DataComponentInterpretation::component_is_scalar to describe + // DataComponentInterpretation::component_is_scalar to describe // the grouping of the pressure variable. // The rest of the function is then the same as in step-20. @@ -871,12 +870,9 @@ namespace Step22 data_component_interpretation); data_out.build_patches (); - std::ostringstream filename; - filename << "solution-" - << Utilities::int_to_string (refinement_cycle, 2) - << ".vtk"; - - std::ofstream output (filename.str().c_str()); + std::ofstream output ("solution-" + + Utilities::int_to_string(refinement_cycle, 2) + + ".vtk"); data_out.write_vtk (output); } diff --git a/examples/step-31/step-31.cc b/examples/step-31/step-31.cc index 2684fab57e..8a5aa28a5d 100644 --- a/examples/step-31/step-31.cc +++ b/examples/step-31/step-31.cc @@ -70,7 +70,6 @@ #include #include #include -#include #include @@ -1942,8 +1941,8 @@ namespace Step31 // using the DataComponentInterpretation helper class. Next, we actually // attach the data vectors with their DoFHandler objects, build patches // according to the degree of freedom, which are (sub-) elements that - // describe the data for visualization programs. Finally, we set a file name - // (that includes the time step number) and write the vtk file. + // describe the data for visualization programs. Finally, we open a file + // (that includes the time step number) and write the vtk data into it. template void BoussinesqFlowProblem::output_results () const { @@ -1966,10 +1965,9 @@ namespace Step31 "T"); data_out.build_patches (std::min(stokes_degree, temperature_degree)); - std::ostringstream filename; - filename << "solution-" << Utilities::int_to_string(timestep_number, 4) << ".vtk"; - - std::ofstream output (filename.str().c_str()); + std::ofstream output ("solution-" + + Utilities::int_to_string(timestep_number,4) + + ".vtk"); data_out.write_vtk (output); } diff --git a/examples/step-37/step-37.cc b/examples/step-37/step-37.cc index 9f3f6f42d6..f19600b3c8 100644 --- a/examples/step-37/step-37.cc +++ b/examples/step-37/step-37.cc @@ -58,7 +58,6 @@ #include #include -#include namespace Step37 @@ -1129,29 +1128,23 @@ namespace Step37 data_out.add_data_vector (solution, "solution"); data_out.build_patches (); - std::ostringstream filename; - filename << "solution-" - << cycle - << "." << Utilities::MPI::this_mpi_process(MPI_COMM_WORLD) - << ".vtu"; - - std::ofstream output (filename.str().c_str()); + std::ofstream output ("solution-" + + std::to_string(cycle) + + "." + + std::to_string(Utilities::MPI::this_mpi_process(MPI_COMM_WORLD)) + + ".vtu"); data_out.write_vtu (output); if (Utilities::MPI::this_mpi_process(MPI_COMM_WORLD) == 0) { std::vector filenames; for (unsigned int i=0; i q_mapping(degree, dof_handler_ref, soln); data_out.build_patches(q_mapping, degree); - std::ostringstream filename; - filename << "solution-" << dim << "d-" << time.get_timestep() << ".vtk"; - - std::ofstream output(filename.str().c_str()); + std::ofstream output ("solution-" + + std::to_string(dim) + + "d-" + + std::to_string(time.get_timestep()) + + ".vtk"); data_out.write_vtk(output); } diff --git a/examples/step-45/step-45.cc b/examples/step-45/step-45.cc index 9220696180..2acf15a42f 100644 --- a/examples/step-45/step-45.cc +++ b/examples/step-45/step-45.cc @@ -676,14 +676,11 @@ namespace Step45 data_out.add_data_vector (subdomain, "subdomain"); data_out.build_patches (mapping, degree+1); - std::ostringstream filename; - filename << "solution-" - << Utilities::int_to_string (refinement_cycle, 2) - << "." - << Utilities::int_to_string (triangulation.locally_owned_subdomain(),2) - << ".vtu"; - - std::ofstream output (filename.str().c_str()); + std::ofstream output ("solution-" + + Utilities::int_to_string(refinement_cycle, 2) + + "." + + Utilities::int_to_string (triangulation.locally_owned_subdomain(),2) + + ".vtu"); data_out.write_vtu (output); if (Utilities::MPI::this_mpi_process(MPI_COMM_WORLD) == 0) diff --git a/examples/step-46/step-46.cc b/examples/step-46/step-46.cc index ea65948ea1..b6cb342b43 100644 --- a/examples/step-46/step-46.cc +++ b/examples/step-46/step-46.cc @@ -60,7 +60,6 @@ #include #include -#include namespace Step46 @@ -910,12 +909,9 @@ namespace Step46 data_component_interpretation); data_out.build_patches (); - std::ostringstream filename; - filename << "solution-" - << Utilities::int_to_string (refinement_cycle, 2) - << ".vtk"; - - std::ofstream output (filename.str().c_str()); + std::ofstream output ("solution-" + + Utilities::int_to_string(refinement_cycle, 2) + + ".vtk"); data_out.write_vtk (output); } diff --git a/examples/step-5/step-5.cc b/examples/step-5/step-5.cc index 16a7b31316..ad8182aa1c 100644 --- a/examples/step-5/step-5.cc +++ b/examples/step-5/step-5.cc @@ -54,9 +54,7 @@ // This is C++ ... #include #include -// ... and this is too: We will convert integers to strings using the C++ -// stringstream class ostringstream: -#include + // Finally, this has been discussed in previous tutorial programs before: using namespace dealii; @@ -344,28 +342,10 @@ void Step5::output_results (const unsigned int cycle) const // Finally, we need the filename to which the results are to be written. We // would like to have it of the form solution-N.eps, where N is // the number of the refinement cycle. Thus, we have to convert an integer - // to a part of a string; this can be done using the sprintf - // function, but in C++ there is a more elegant way: write everything into a - // special stream (just like writing into a file or to the screen) and - // retrieve what you wrote as a string. This applies the usual conversions - // from integer to strings, and one could as well use stream modifiers such - // as setw, setprecision, and so on. In C++, you - // can do this by using the so-called stringstream classes: - std::ostringstream filename; - - // In order to now actually generate a filename, we fill the stringstream - // variable with the base of the filename, then the number part, and finally - // the suffix indicating the file type: - filename << "solution-" - << cycle - << ".eps"; - - // We can get whatever we wrote to the stream using the str() - // function. The result is a string which we have to convert to a char* - // using the c_str() function. Use that as filename for the - // output stream and then write the data to the file: - std::ofstream output (filename.str().c_str()); - + // to a part of a string; this is most easily done using the C++ function + // std::to_string. With the so-constructed filename, we can + // then open an output stream and write the data to that file: + std::ofstream output ("solution-" + std::to_string(cycle) + ".eps"); data_out.write_eps (output); } diff --git a/examples/step-56/step-56.cc b/examples/step-56/step-56.cc index 4b5632bb4f..cf243aa738 100644 --- a/examples/step-56/step-56.cc +++ b/examples/step-56/step-56.cc @@ -72,8 +72,8 @@ #include #include +#include #include -#include namespace Step56 { @@ -1047,12 +1047,9 @@ namespace Step56 data_component_interpretation); data_out.build_patches (); - std::ostringstream filename; - filename << "solution-" - << Utilities::int_to_string (refinement_cycle, 2) - << ".vtk"; - - std::ofstream output (filename.str().c_str()); + std::ofstream output ("solution-" + + Utilities::int_to_string(refinement_cycle, 2) + + ".vtk"); data_out.write_vtk (output); } diff --git a/examples/step-57/step-57.cc b/examples/step-57/step-57.cc index a1d7adfef9..ca3b6302db 100644 --- a/examples/step-57/step-57.cc +++ b/examples/step-57/step-57.cc @@ -70,7 +70,6 @@ #include #include -#include namespace Step57 { @@ -754,7 +753,9 @@ namespace Step57 } // @sect4{StationaryNavierStokes::output_results} - // This function is the same as in step-22. + // This function is the same as in step-22 except that we choose a name + // for the output file that also contains the Reynolds number (i.e., the + // inverse of the viscosity in the current context). template void StationaryNavierStokes::output_results (const unsigned int output_index) const { @@ -773,13 +774,10 @@ namespace Step57 data_component_interpretation); data_out.build_patches (); - std::ostringstream filename; - filename << 1.0/viscosity - << "-solution-" - << Utilities::int_to_string (output_index, 4) - << ".vtk"; - - std::ofstream output (filename.str().c_str()); + std::ofstream output (std::to_string(1.0/viscosity) + + "-solution-" + + Utilities::int_to_string (output_index, 4) + + ".vtk"); data_out.write_vtk (output); } @@ -790,10 +788,10 @@ namespace Step57 template void StationaryNavierStokes::process_solution(unsigned int refinement) { - std::ostringstream filename; - filename << (1.0/viscosity) << "-line-" << refinement << ".txt"; - - std::ofstream f (filename.str().c_str()); + std::ofstream f (std::to_string(1.0/viscosity) + + "-line-" + + std::to_string(refinement) + + ".txt"); f << "# y u_x u_y" << std::endl; Point p; -- 2.39.5