C++ Handling super basic errors how should I do this? - c++

double ctok(double c) // converts Celsius to Kelvin
{
if (c <= -273.15)
{
cout << "Temp too low.";
exit(1);
}
else {
double k = c + 273.15;
return k;
}
}
int main()
{
double c = 0;
cin >> c; // retrieve temperature to input variable
double k = ctok(c); // convecout << rt temperature
cout << k << '/n'; // print out temperature
}
So if c is smaller or equal to -273.15 I want to basically stop the program and I wanna do all this in the ctok function so I just check with an if statement and then use exit() but something here just seems off and I feel like this isn't a good way to handle it.. I've also heard using exit isn't really good but my only other idea is to handle this with exceptions:
So I add this function definition:
void error(string s)
{
throw runtime_error(s);
}
Then I can just do this:
double ctok(double c) // converts Celsius to Kelvin
{
if (c <= -273.15)
{
error("Temp too low.");
}
double k = c + 273.15;
return k;
}
int main()
{
try {
double c = 0;
cin >> c; // retrieve temperature to input variable
double k = ctok(c); // convecout << rt temperature
cout << k << '/n'; // print out temperature
}
catch (runtime_error a)
{
cout << a.what();
}
}
But this also feels a little overkill for handling such a simple error doesn't it? So I just wanna know is there like some good basic way to deal with such a basic error?

You could make ctok return bool and pass a pointer or reference to a variable and store the result:
bool ctok(double c, double *pr)
if( ! ctok( c, &k ) )
cout << "error\n";
or simply ctok() should throw itself the exception instead of a function that do nothing more than a throw...
IMO, both are simple solutions for a simple program, even with your 'error()' function.

Related

How can I simplify this program? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
I'm writing a program that finds the roots of a quadratic equation using exception handling and i'm wondering if there's a way I can simplify the program, I have a bunch of empty classes for the catch cases
// Program to solve quadratic equation
#include <iostream>
#include <cstdlib>
#include <cmath>
using namespace std;
class all_zero{
};
class negative{
};
class zero_division{
};
void roots(double a, double b, double c) throw (all_zero,negative,zero_division);
int main(){
double a, b, c; // coefficient of ax“2 + bx + c= 0
cout << "Enter the three coefficients \n";
cin >> a >> b >> c;
try
{
roots(a, b, c);
}
catch(all_zero) {cout << "All values are zero \n";}
catch(negative) {cout << "Square root of negative values is not defined \n";}
catch(zero_division) {cout << "Division by zero, not defined \n";}
return 0;
}
void roots(double a, double b, double c) throw (all_zero,negative,zero_division){
double x1, x2; // The two roots
double temp;
if(!(a== 0 && b== 0 && c==0)){
if(a != 0){
temp = b*b - 4*a*c;
if(temp >= 0){
x1 =(-b + sqrt(temp))/2*a;
x2 = (-b - sqrt(temp))/2*a;
cout << "The two roots are: "<< x1 <<" and " << x2 << endl;
}else{throw negative();}
}else{throw zero_division();}
}else{throw all_zero();}
}
Is there a way I can make it so i dont have just empty classes or a way to put them into maybe a struct?
Note that the dynamic excpetion specification you are using is deprecated in C++11 and removed in C++17:
void roots(double a, double b, double c) throw (all_zero,negative,zero_division)
// ^^
You can just remove it.
using namespace std; is considered bad practice.
Do not use std::endl to add a newline. std::endl adds a new line and flushes the stream. Most of the time this is unnecessary. Use '\n' to add a newline.
Is there a way I can make it so i dont have just empty classes or a way to put them into maybe a struct?
Actually, I don't see the bad about having seperate classes for the different types of exceptions. The downside of your approach is that the "what" is in the catch, not part of the exception or coming from where the exception occured. I'll show you the first (message is part of the type) and hope you will see how to realize the latter (message is from where the exception is thrown).
You can inherit from std::runtime_error which offers a what() method that returns a string passed to the constructor. This also makes it easier for others to catch your exceptions, because std::runtime_error in turn inherits from std::excpetion which is the base class of all standard exceptions:
// Program to solve quadratic equation
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <stdexcept>
struct all_zero : std::runtime_error {
all_zero() : std::runtime_error("All values are zero") {}
};
struct negative : std::runtime_error {
negative() : std::runtime_error("Square root of negative values is not defined") {}
};
struct zero_division : std::runtime_error {
zero_division() : std::runtime_error("Division by zero, not defined") {}
};
void roots(double a, double b, double c);
int main(){
double a, b, c; // coefficient of ax“2 + bx + c= 0
std::cout << "Enter the three coefficients \n";
std::cin >> a >> b >> c;
try
{
roots(a, b, c);
}
catch(std::runtime_error& ex) {std::cout << ex.what() << '\n';}
return 0;
}
void roots(double a, double b, double c) {
double x1, x2; // The two roots
double temp;
if(!(a== 0 && b== 0 && c==0)){
if(a != 0){
temp = b*b - 4*a*c;
if(temp >= 0){
x1 =(-b + sqrt(temp))/2*a;
x2 = (-b - sqrt(temp))/2*a;
std::cout << "The two roots are: "<< x1 <<" and " << x2 << "\n";
}else{throw negative();}
}else{throw zero_division();}
}else{throw all_zero();}
}
Live Demo
Note that exceptions should be catched as reference, otherwise there will be object slicing when the exception is derived. And as in general you don't know what type of exception you will catch, you need to be careful to avoid that.
Alternatively you could use a more general exception type (roots_exception?) and instead of hardcoding the "what" pass it to the constructor when you throw it.
There is probably more you can improve, for which I suggest you https://codereview.stackexchange.com/.
PS: I tried to keep style aside, though one more thing you should change is to return the result from the function, instead of just printing it to the screen. If you want to use the result for other calcualtions you currently cannot. Perhaps you were puzzled how to return two values. std::pair makes that simple:
std::pair<double,double> roots(...) {
// ...
return {x1,x2};
}
and then:
try {
auto result = roots(a,b,c);
std::cout << "The two roots are: "<< result.first <<" and " << result.second << "\n";
}
My input:
Make sure the formula is correct. The /2*a part should be /(2*a).
Define an error category for your solver's errors and inherit more specific errors from that.
Remove unnessary tests (a== 0 && b== 0 && c==0). You already check if a == 0, so if a != 0 but b and c are, the solution will be 0, which should be valid.
Reverse the tests to not have to throw in an else. Throw early to not have deep nested if's.
Return the result, don't print it. I've added tweaks to make it possible to solve linear and complex equations too (in comments), but you can skip that if you want. This shows how you can return multiple values though.
Don't do forward declaration unless you really have to.
Read Why is using namespace std; considered bad practice?
More details in comments in the code
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <stdexcept>
#include <tuple> // std::tuple - used for returning multiple values here
struct solver_error : std::runtime_error { // your solver's error category
using std::runtime_error::runtime_error;
};
struct unknown_error : solver_error {
unknown_error() : solver_error("x is unknown") {}
};
struct linear_error : solver_error {
linear_error() : solver_error("cant solve linear equation") {}
};
struct complex_error : solver_error {
complex_error() : solver_error("cant solve complex equation") {}
};
// add more exceptions to the solver_error exception category if needed
// now returns two values and a bool to indicate if the solution is complex
std::tuple<double, double, bool> solve_for_x(double a, double b, double c) {
if(a == 0) throw linear_error(); // throw early
/* ... or solve it as a linear equation:
if(a == 0) {
if(b == 0) throw unknown_error(); // both a and b == 0, x is unknown
double res = -c / b;
return {res, res, false}; // only one x and not complex
}
*/
double div = 2 * a;
double temp = b * b - 4 * a * c;
if(temp < 0) throw complex_error();
/* ... or solve it as a complex equation
if(temp < 0) {
double sqr = sqrt(-temp); // sqrt of the positive temp instead
return {-b / div, sqr / div, true}; // real, imaginary and complex==true
}
*/
// real quadratic
double sqr = sqrt(temp);
double x1 = (-b + sqr) / div; // corrected formula (div = 2*a)
double x2 = (-b - sqr) / div; // corrected formula
return {x1, x2, false}; // return the two values and complex==false
}
int main() {
// make the user aware of what the coefficients are for
std::cout << "Enter the three coefficients a, b and c in the equation\n"
"ax^2 + bx + c = 0\n";
double a, b, c;
try {
// check that extracting the numbers succeeds
if(not(std::cin >> a >> b >> c)) throw std::runtime_error("input error");
// get the three return values via structured bindings
auto [first, second, complex] = solve_for_x(a, b, c);
std::cout << "x = ";
if(complex) // complex quadratic
std::cout << first << " ± " << second << 'i';
else if(first == second) // linear
std::cout << first;
else // real quadratic
std::cout << '{' << first << ',' << second << '}';
std::cout << '\n';
} catch(const solver_error& ex) {
// catching the generic error category by "const&"
std::cerr << "Solver error: " << ex.what() << '\n';
return 1;
} catch(const std::runtime_error& ex) {
std::cerr << ex.what() << '\n';
return 1;
}
}

Reading into an Array Multiple Times

I'm having a little trouble with my code. It's pretty much supposed to open two files, and compare the first twenty line of the file "StudentAnswers.txt" [inputted as a char into a char array] against a char value in (each line of another file) "CorrectAnswers.txt" in another array at the same position (index). It's like a linear search, but the same position in the arrays. Then a report should be displayed, detailing which question the student missed, the given answer, the correct answer, and if the student passed (got >= 70%) or not, like the following:
Report for Student X:
2 (A/D), 3 (C/D), 5(D/A)
This student passed the exam!
Then it should clear the SAArray, and feed the next twenty lines from StudentAnswers.txt, and start the process all over again. I guess the program has to determine the number of students from (lines of 'StudentAnswers.txt' file / 20).
I'm having trouble displaying the report, and having the array clear itself after the program. I'm guessing this can be done with a while loop and an accumulator for the number of students (to be determined by above equation).
Also, Visual Studio seems to go to "Missed __ questions for a total of ___ %", and then keep looping -858993460.
Any help would be appreciated.
#include <iostream>
#include <fstream>
#include <string>
#include <array>
#include <algorithm>
using namespace std;
void GradeReturn(char[], char[], int, int, int);
string PassFail(float);
int main()
{
ifstream SA("StudentAnswers.txt");
ifstream CA("CorrectAnswers.txt");char CAArray[20];
char SAArray[20];
// char SA2Array[20];
bool isCorrect;
int correct;
int incorrect;
int counter;
correct = 0;incorrect = 0;
counter = 0;
cout << endl;
if (!SA.fail())
{
cout << "'StudentAnswers.txt' file opened successfully." << endl;
cout << "'CorrectAnswers.txt' file opened successfully." << endl << endl;
int a = 0;
int b = 0;
while (a < 20)
{
CA >> CAArray[a];
a++;
} // while loop to feed char into the array
while (b < 20)
{
SA >> SAArray[b];
b++;
}
} // while loop to feed char into array
CA.close(); // closing "CorrectAnswers.txt"
SA.close(); // closing "StudentAnswers.txt"
GradeReturn(&CAArray[counter], &SAArray[counter], correct, incorrect, counter);
return 0;
}
void GradeReturn(char CAArray[], char SAArray[], int correct, int incorrect, int counter)
{
float percent;
float hundred;
int student;
int catcher[20];
int writeCatcher; int starter;
int catcher_size;
student = 0;
writeCatcher = 0;
catcher_size = ((sizeof catcher) / 4);
while (counter < 20)
{
if ((CAArray[counter]) == (SAArray[counter]))
{
correct++;
cout << "Good job!" << endl;
} // correct handling
else
{
incorrect++;
cout << "You got question " << counter << " wrong." << endl;
counter >> catcher[writeCatcher];
writeCatcher++;
} // incorrect handling
counter++;
} // while loop to determine if a student got a question right or wrong
static_cast <float> (incorrect); // float conversion
cout << endl; // for cleanliness
percent = ((static_cast <float> (correct)) / 20); // percentage
hundred = percent * 100;
PassFail(percent);
if (PassFail(percent) == "pass")
{
student++;
cout << "Report for Student " << student << ":" << endl;
cout << "-----------------------------" << endl;
cout << "Missed " << incorrect << " questions out of 20 for ";
cout << hundred << " % correct." << endl << endl;
starter = 0;
while (starter < (sizeof catcher)
{
if(1=1)
{
catcher_size
}
else
{
cout << "";
starter++;
}
}
}
else if (PassFail(percent) == "fail")
{
student++;
cout << "Missed " << incorrect << " questions out of 20 for ";
cout << hundred << " % correct." << endl << endl;
while (starter < catcher_size)
{
if ((catcher[starter]) == -858993460)
{
starter++;
}
else
{
cout << "";
starter++;
}
}
}
return;
}
string PassFail(float percent)
{
if (percent >= 0.70) // if <pass>
{
return "pass";
}
else // if <fail>
{
return "fail";
}
cout << endl;
}
To get a loop you should keep streams open instead of closing them after reading 20 lines.
As pseudo code that would be:
a = 0;
while(streams_not_empty)
{
CA >> CAArray[a];
SA >> SAArray[a];
++a;
if (a == 20)
{
GradeReturn(&CAArray[counter], &SAArray[counter], correct, incorrect, counter);
a = 0; // Reset a
}
}
CA.close(); // closing "CorrectAnswers.txt"
SA.close(); // closing "StudentAnswers.txt"
You would also need to pass correct, incorrect, counter by reference so that the GradeReturn can change their value and their by do the accumulation.
Like:
void GradeReturn(char CAArray[], char SAArray[], int& correct, int& incorrect, int& counter)
Further you shouldn't rely on being able to read exactly Nx20 lines from the files every time. A file could have, e.g. 108 (5x20 + 8) lines, so you code should be able to handle the with only 8 lines. In other words, don't hard code 20 in your function like while (counter < 20). Instead pass the number of lines to be handled and do while (counter < number_to_handle).
Something like this as pseudo code:
a = 0;
while(streams_not_empty)
{
CA >> CAArray[a];
SA >> SAArray[a];
++a;
if (a == 20)
{
GradeReturn(&CAArray[counter], &SAArray[counter], correct, incorrect, counter, a);
// ^
a = 0; // Reset a
}
}
if (a != 0)
{
// Process the rest
GradeReturn(&CAArray[counter], &SAArray[counter], correct, incorrect, counter, a);
}
CA.close(); // closing "CorrectAnswers.txt"
SA.close(); // closing "StudentAnswers.txt"
One problem you have is you're trying to compare C-style strings with the == operator. This will compare them essentially as if they were pointers to char, i.e. compare whether they point at the same location in memory, not compare the contents of the string. I urge you to look up array-decay and c-string variables to understand more.
Specifically, if (PassFail(percent) == "pass") isn't going to do what you want it to. strcomp doc, strncmp doc using std::string variables instead of c-style strings would all work, but it would be better simply to compare percent to a value, i.e. if(percent >= 0.70 directly instead of calling PassFail and comparing a string.
There are many other issues here also, you at one point call PassFail but do nothing with the return value. The only side affect of PassFail is cout << endl, if that's what you intend, it's a poor decision and hard to read way to put a newline on the console.
Try asking your compiler for more warnings, that's often helpful in finding these types of issues. -Wall -Wextra work for gcc, you may have to read your compiler manual...

Why does my vector size keep resetting to 0? (currently using classes)

I've been trying to make a polynomial class, and I've got almost half of it done. However, my vectors keep resetting to 0 after "polynomial q(coeff, expo);", can anyone tell me why?
class polynomial {
public:
polynomial();
polynomial(vector<float> coefficient, vector<int> degree);
friend ostream& operator<<(ostream& os, const polynomial& y);
private:
vector<float> coeff1;
vector<int> expo1;
};
polynomial::polynomial(){
coeff1.clear();
expo1.clear();
coeff1.push_back(1);
}
polynomial::polynomial(vector<float> coefficient, vector<int> degree){
if (coefficient.size() != degree.size()){
cout << "Error. The number of coefficients are not the same as the number of exponents. Polynomial will be set to 1." << endl;
polynomial();
}
else {
for (int b = 0; b<degree.size(); b++) {
for (int c = 0; c<b; c++){
if (degree[b] > degree[c]){
int holder = degree[b];
degree[b] = degree[c];
degree[c] = holder;
float holder1 = coefficient[b];
coefficient[b] = coefficient[c];
coefficient[c] = holder1;
}
}
}
for (int a = 0; a<coefficient.size(); a++) {
coeff1.push_back (coefficient[a]);
expo1.push_back (degree[a]);
}
}
}
ostream& operator<<(ostream& os, const polynomial& y){
if (y.coeff1.size() != y.expo1.size()) {
os << 1;
return os;
}
else {
for (int x = 0; x<y.coeff1.size(); x++){
if (y.coeff1[x] != y.coeff1[y.coeff1.size() - 1]) {
if (y.expo1[x] == 1){
os << y.coeff1[x] << "x" << " + ";
}
else if(y.expo1[x] == 0) {
os << y.coeff1[x];
}
else {
os << y.coeff1[x] << "x^" << y.expo1[x] << " + ";
}
}
else {
if (y.expo1[x] == 1){
os << y.coeff1[x] << "x";
}
else if(y.expo1[x] == 0) {
os << y.coeff1[x];
}
}
}
return os;
}
}
int main()
{
vector<float> coeff;
vector<int> expo;
coeff.push_back(3);
coeff.push_back(16);
coeff.push_back(10);
// coeff.push_back(7);
expo.push_back(4);
expo.push_back(1);
expo.push_back(2);
expo.push_back(3);
polynomial p;
cout << "The polynomial is: " << p << endl;
polynomial q(coeff, expo);
cout << "The polynomial is: " << q << endl;
return 0;
}
[there are useless lines of code because i wanted to check where the size of my vector was changing to 0]
This line:
polynomial();
creates an unnamed object and immediately destroys it. It has the same effect as:
{
polynomial x;
}
I guess you were trying to "call the constructor". However this is not possible, constructors are special and can only be 'called' by virtue of the attempt to create an object; or from the ctor-initializer list .
I would suggest redesigning your constructors. Firstly, the copy-constructor is bogus (it doesn't copy any of the fields except ptr, and also int *ptr was not initialized by the normal constructors). In fact int *ptr; should be removed entirely.
In the constructor polynomial() , the calls to clear() are redundant. Vectors start off empty, and since this is a constructor, it's only called on a polynomial that is just in the business of being created for the first time.
I would suggest doing this for the constructor taking two arguments:
polynomial::polynomial(vector<float> coefficient, vector<int> degree)
{
if (coefficient.size() != degree.size())
{
// typically it would be better to just throw an exception here, the caller will not expect a 1-polynomial
std::cerr << "Error. The number of coefficients are not the same as the number of exponents. Polynomial will be set to 1." << std::endl;
coeff1.push_back(1);
wala();
}
else
{
set_polynomial(coefficient, degree);
}
}
and move your other logic for sorting the coefficient and degree into a private function called set_polynomial. This keeps your constructor easy to read and your code tidy; you may want to use this function at a later time to allow the user to change a polynomial.
Pro tip: look into std::tie, you can actually sort coefficient and degree together using a single command.

Conversion Fahrenheit to Celsius using class c

Hello everyone I'm having a problem. I'm fairly new and been stuck trying to solve it.
When I run it the first part where it prints 0 for the Fahrenheit to Celsius is correct but once I input a number it just prints the number I input. I know it probably a simple answer but thank you for your time.
#include <iostream>
using namespace std;
class Temp
{
public:
Temp(); //CONSTRUCTOR: Sets private variable for Fahrenheit to 32
void InputF(float F); //Initialize Fahrenheit temperature to F
void Celsius(); //PRINTS the Celsius temperature corresponding to
// the private Fahrenheit equivalent temperature
void ChangeBy(float D); //Changes the private Fahrenheit temperature
// by D degrees.
float Fahrenheit(); // returns the value of the private Fahrenheit temp
private:
float Fah; //Fahrenheit Temperature
};
int main() {
float FF;
Temp T; // Temperature Object
T.Celsius();
cout << endl; //Note that the value will be 0 since the private variable is 32.
cout << "Input a Fahrenheit temp: ";
cin >> FF;
T.InputF(FF);
cout << T.Fahrenheit() << endl;;
T.ChangeBy(34);
cout << T.Fahrenheit() << endl;
system("Pause");
return 0;
}
Temp::Temp() {
Fah = 32;
}
void Temp::InputF(float F) {
Fah = F;
}
void Temp::Celsius() {
cout << Fah;
}
void Temp::ChangeBy(float D) {
Fah = (5.0 / 9) * (Fah - 32);
}
float Temp::Fahrenheit() {
return Fah;
}
So, one issue:
void Temp::ChangeBy(float D)
{
Fah = (5.0/9)* (Fah - 32);
}
This method does not do what you say it does in the class declaration; your comment says that it updates Fah by the number of Fahrenheit degrees passed to it.
If I may suggest the following changes:
First, have ChangeBy simply add the input value to Fah:void Temp::ChangeBy( float D )
{
Fah += D;
}
Second, have the Celcius method do the conversion and return the converted value:float Temp::Celcius()
{
return (5.0/9.0) * (Fah - 32.0);
}
Finally, in your main function, write the output of Temp::Celcius() to the output stream:std::cout << T.Celcius() << std::endl;
EDIT
I took the liberty of rewriting your code to show what I mean; there isn't enough space in a single comment to really get the point across:
#include <iostream>
using namespace std;
class Temp
{
public:
Temp( float f = 32.0 ); // slight change here
void InputF(float F);
float Celsius() const; // note return type, addition of const
void ChangeBy(float D);
float Fahrenheit() const; // note addition of const
private:
float Fah;
};
int main() {
float FF;
Temp T;
cout << T.Celsius(); // Note that we output the result of Celsius in
// exactly the same manner that we do for
// Fahrenheit below.
cout << endl;
cout << "Input a Fahrenheit temp: ";
cin >> FF;
T.InputF(FF);
cout << T.Fahrenheit() << endl;
T.ChangeBy(34);
cout << T.Fahrenheit() << endl;
return 0;
}
/**
* Slight change here; we're using a member initializer, rather than
* assigning Fah in the body of the constructor. For a simple class
* like this it doesn't matter, but when you start getting into derived
* and virtual classes, using this method will make sure things get
* initialized in the right places and in the right order.
*/
Temp::Temp( float f ) : Fah(f) {
}
void Temp::InputF(float F) {
Fah = F;
}
float Temp::Celsius() const {
return (5.0f / 9.0f) * ( Fah - 32.0f ); // use f suffix for float constants
}
void Temp::ChangeBy(float D) {
Fah += D; // Update the value of Fah by the input value; the code you
// posted isn't using the value of D to update Fah, it was
// simply converting Fah to Celsius.
}
float Temp::Fahrenheit() const {
return Fah;
}
This code builds and runs on a Linux system using g++ with the -pedantic -Wall -Werror flags.
So, I've changed the return type of Celsius from void to float; instead of having Celsius print the value, it simply returns the value to main. This way Celsius doesn't have to worry about where the output gets written (what if you wanted to write to a file instead of cout, for example), and its focus is now much narrower.
I also changed the ChangeBy function; in the implementation you pasted above, you aren't actually using the input parameter D to change the value of Fah; you're simply converting the value of Fah from Fahrenheit to Celcius.
Notice that I also added the trailing const qualifier to the Fahrenheit and Celsius methods. This indicates that these two methods will not attempt to update any data internal to Temp. It's a good idea to make such "query" methods const in this manner; it keeps you from writing code that makes changes where it shouldn't.

In c++ how to avoid print message when I use function which has cout?

If i have two functions A and B, A will print message when we use A. B will use A, but when I use B, I do not want to print anything. How can I do this?
double CTriangle::perimeter() const{
double D = Distance(A, B) + Distance(A, C) + Distance(B, C);
cout << "Perimeter of this triangle is: " << D << endl;
return D;
}
double CTriangle::area() const{
double p = this->perimeter() / 2;
double Area = sqrt(p * (p - Distance(A, B)) * (p - Distance(A, C)) * (p - Distance(B, C)));
cout << "Area of this triangle is: " << Area << endl;
return Area;
}
How about adding a parameter to A(), e.g.
void A(bool verbose = true)
{
if (verbose) cout << "Hello world!" << endl;
}
void B()
{
A(false);
}
int main()
{
A(); // outputs "Hello world!"
B(); // calls A, but no output
return 0;
}
Assuming you don't have any control over the function which does the printing, you can put std::cout into a state where it won't print anything, e.g.:
std::cout.setstate(std::ios_base::failbit); // set error flag, disabling output
double d = this->perimeter();
std::cout.clear(); // clear flags, reenabling output
You can reasonably view the stream state a resource, i.e., it may be reasonable to use RAII to make sure the stream's state gets restored.
If you can change the function which does the unwanted output, I'd recommend rewriting this function to become two functions:
One function which doesn't do any logging and implements the core functionality.
Another function which does logging and calls the other function for the actual functionality.