while loop continues after sentinel value is reached - c++11

I'm currently confused on while loops, specifically why the loop still runs everything else in the loop specifically after the sentinel value is reached...
here's the example of my code below:
while (quit != -1) {
cout<<"Options: a)ir; w)ater; s)teel; q)uit \n";
char option=' ';
cin>>option;
option = toupper(option);
while( option != 'A' && option != 'W' && option != 'S' && option != 'Q'){
cin.clear();
cout<<"INVALID INPUT!! \n";
cin>>option;
option = toupper(option);
}
switch(option){
case 'Q':
cout<<"You Have Quit!";
quit = -1;
break;
}
cout<<"Please input the distance: \n";
double distance=0;
cin>>distance;
while(distance < 0){
cin.clear();
cout<<"INVALID INPUT \n";
cin>>distance;
}
switch(option){
case 'A':
seconds = distance/speed_a;
cout<< "Time travled: " << setprecision(2) << fixed << seconds << "\n";
break;
case 'W':
seconds = distance/speed_w;
cout<< "Time travled: " << setprecision(2) << fixed << seconds << "\n";
break;
case 'S':
seconds = distance/speed_s;
cout<< "Time travled: " << setprecision(2) << fixed << seconds << "\n";
break;
}
}
basically when the user enters the 'q' character it runs the quit switch statement... it does quit the loop but it still asks for the distance traveled before ending the loop..
output is shown below:
Options: a)ir; w)ater; s)teel; q)uit
q
You Have Quit!
Please input the distance:
0
--------------------------------
Process exited after 2.944 seconds with return value 0
Press any key to continue . . .
is there any way to edit the code so it immediately quits the loop or is this just the way all loops are pre-programmed?
any advice would be appreciated

The break statement Inside a switch case only exits the switch block, not the outer while loop. Your code continues to run until the next evaluation of the while loop condition.

Related

C++ empty() and all_of() for checking string is empty or have only digit

I'm creating an IO console application and at the inputs i got an 'while' loop with two condition
empty() and all_of(), the function all_of() seems to work properly but when i press enter the empty() function not working and just let me to input the next thing in the 'struct'. I'm not sure am i doing it correct..There is the part of the code
cout << "Enter age: ";
getline(cin, age_str);
while(!age_str.empty() && !all_of(age_str.begin(), age_str.end(), ::isdigit)){
cout << "--Please Enter an integer-- " << endl;
cin.clear();
getline(cin, age_str);
}
stringstream(age_str) >> person_arr[n].age;
There are a link to the full code : enter link description here
The logic of the conditional of the while is incorrect.
What you need to do is:
If the line is empty, get the next line.
If the line is not empty and the line has anything other than digits, get the next line.
!age_str.empty() && !all_of(age_str.begin(), age_str.end(), ::isdigit) does not do that.
You need to use age_str.empty() || (!all_of(age_str.begin(), age_str.end(), ::isdigit))
I always recommend, when in doubt, simplify.
while ( !is_input_valid(age_str)) )
{
...
}
where
bool is_input_valid(std::string const& input)
{
if ( input.empty() )
{
return false;
}
return std::all_of(input.begin(), input.end(), ::isdigit);
}

why does my code skip the if statement and go to the else when i open the file

my assignment asks me to open a file, but if it doesn't open you are given 3 tries, but when I input the correct file on my second and third try it still give me the error I wrote 'ERROR: File " << input_filename << " could not be opened for input"' and goes to my else statement
char input_filename[90];
ifstream input;
cout << "Type the name of the input file which will hold the simulation results : " << endl;
cin>> input_filename;
input.open(input_filename);
if (input.fail())//if the file doesn't open it will go to the do while loop error message
{
int i = 0;
int h = 0;
do
{
cout << "ERROR: File " << input_filename << " could not be opened for input" << endl;
cin >> input_filename;// allows user to reinput filename
input.open(input_filename);//opens file
if ( !input.fail())
{
cout << "if statement" << endl;
h++;// if h doesn't equal 1 it goes out of the loop
}
else
{
cout << "else statement" << endl;
i++;//post-decrement allows for 2 more tries to input file
}
if (i >= 2)
{
cout << "ERROR: You exceeded maximum number of tries allowed" << endl;
cout << "while entering the input file name" << endl;
return 1;// return 1 represents the error of the input not opening after the 3rd time of inputing
}
} while (i < 2 && h != 0);// do while because it need to be a post condition for two varibles
}
If you reach line 106, it implies your file input succeeded. At that line you should NOT increment h. In fact you should leave h at zero if you want to break out of the loop (Assuming the file input worked).

Big O of Switch statement having function calls in its Cases?

How can we calculate Big O of switch statement whom are having function calls in there cases. that Function can be the Function in whom the switch statement is present and can also direst to another function whom can send it back to the same Switch statement.
void ifpascorrectSwitch(int *currentbalance) {
cout << "\n\n";
cout << "Current balance = £" << *currentbalance << endl;
string casee;
cout << "Enter any of the below option\n"
"1 for Deposit cash \n"
"2 for Withdraw cash\n"
"e for Quiting the application\n"
"= ";
cin >> casee;
if (casee.length() == 1) {
const char *k = casee.c_str(); // character inter to a c string
switch (*k) {
case '1':
cout << "1 Deopist cash \n";
Depositcash(currentbalance);
//Deposit is another function call whom can can come back to this function
// and have this switch menu again because of bellow given //ifpascorrectSwitch(currentbalance) which is function call of the current //function
ifpascorrectSwitch(currentbalance);
break;
case '2':
cout << "2 Withdraw menu\n";
WithdrawCash(currentbalance);
ifpascorrectSwitch(currentbalance);
break;
case 'e':
cout << "r is working";
break;
default:
cout << "Default switch wrong entery";
ifpascorrectSwitch(currentbalance);
break;
}
} else {
cout << "Wrong entery please try again";
ifpascorrectSwitch(currentbalance);
} }
All other function call other then ifpascorrectSwitch(currentbalance)which is current function call are having same scenario of switch stament. almost.
If only someone could help me atleast undesrtanding this Switch statement Big O calcultaion.

c++ and global variables changed in functions

I have these variable defined as global variables outside any function
//testing parameters (init to all nonfail)
int serverRandom = 0; //nonzero == fail > gotofail for first sha1 methode
SSLBuffer sigpar= 0; //nonzero == fail > gotofail for second sha1 methode
string hashOut = "nonfail"; //"fail" == error condition > gotofail for third sha1 methode
These variables are used in this function:
static OSStatus SSLVerifySignedServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer signedParams, uint8_t *signature, uint16_t signatureLen)
{
OSStatus err;
cout << "initval:"<< serverRandom<< signedParams<< hashOut<<endl;
if ((err = SSLHashSHA1::update(&hashCtx, &serverRandom)) != 0)
cout << "firstfail" <<endl;
goto fail;
if ((err = SSLHashSHA1::update(&hashCtx, &signedParams)) != 0)
cout <<"secondfail"<<endl;
goto fail;
//goto fail;
if ((err = SSLHashSHA1::final(&hashCtx, &hashOut)) != 0)
cout << "thirdfail" << endl;
goto fail;
cout << "nonfail" << endl;
fail:
SSLFreeBuffer(&signedHashes);
SSLFreeBuffer(&hashCtx);
return err;
}
Note that the global variables ServerRandom and hashout are accessed directly in that function while the sigpar variable is given to the signedParams arguments of the sslVerify function.
Now, I wrote a unit test to test each failing case seperatly via this function
void unittest(){
//all tests passing
cout << "-------------nonfail-------------" << endl;
result = SSLVerifySignedServerKeyExchange(&ctx,isrsa,sigpar,&sig,siglen);
//first test fail
cout << "-------------firstfail-------------" << endl;
serverRandom = 1;
result = SSLVerifySignedServerKeyExchange(&ctx,isrsa,sigpar,&sig,siglen);
serverRandom = 0;
//second test fail
cout << "-------------secondfail-------------" << endl;
sigpar= 1;
result = SSLVerifySignedServerKeyExchange(&ctx,isrsa,sigpar,&sig,siglen);
sigpar= 0;
//third test fail
cout << "-------------thirdfail-------------" << endl;
hashOut = "fail";
result = SSLVerifySignedServerKeyExchange(&ctx,isrsa,sigpar,&sig,siglen);
hashOut = "nonfail";
}
Now it works perfectly for the first fail case eg. outputting the firstfail line. After that It does not work anymore as it just outputs the ---------secondfail-------- & ------thirdfail------- without outputting the failchecks (secondfail/thirdfail).
note that the initval inside sslverify...() shows the correct values, however the update/final function after the first testcause show 0 as a value for the respective values they recieve.
well, it was easy to solve in the end:
in the SSLVerifySignedServerKeyExchange() I just forgot to add {} around the multi-line if's after I added the cout<< so it would always goto fail after the first if

std::cout seems to be printing out an extra "|" when called initially

I am working on a portion of my code that is suppose to output the error message correctly.
Please see below screenshot, I am using on bash
./myProgram < input3a.in | diff -a -y output3a.out -
Left hand side is what I want to get to.
For some reason an extra "|" is printed before the char array 'line' is printed. I suspected that maybe the char array 'line' is not null terminated. but it is initialize by cin.getline(); which should null terminate the char array.
Here i try to print the 'line' array in my main procedure, and it left the | sign on the line before it.
my question is. why does std::cout display this behaviour?
Thanks
EDIT,
Below is my code in question. Thanks for taking a look again.
#include "char_stack.h"
#include <iostream>
void printErrorLine(int errorSpot, int c_count, char line[]){
//Print the first line of error message char by char, at the
//same time replace char with \t or space
for(int x = 0; x <= errorSpot; x++){
std::cout << line[x];
if(line[x] != '\t'){
line[x] = ' ';
}
}
std::cout << std::endl;
//Print out the second line, if the first line does not have a
//errorSpot, then dont print it
if(errorSpot != c_count){
std::cout << line << std::endl;
}
}
char findCounterPart(char bracket){
//pass.
}
int main(int argc, char * argv[]){
char line[250]; // 250 because spec sheet detailed max 250 char per line.
char c;
int l_count = 0; // number of lines already read
int c_count; // character count in a line
char_stack S;
bool isError;
while(!std::cin.peek() == std::cin.eof()){
std::cin.getline(line, 250);
c_count = std::cin.gcount();
l_count +=1;
//std::cout<< c_count << std::endl << std::endl;
//loop through the line
for(int x = 0; x < c_count; x++){
c = line[x];
//std::cout << c << " stack size is " << S.size() << std::endl;
if (c == '(' ||
c == '{' ||
c == '['){
S.push(c);
}
else if(c == ')' ||
c == '}' ||
c == ']'){
if(S.empty()){
std::cout << "Error on line " << l_count << ": Too many " << c << std::endl;
isError = true;
}
else{
char l = S.pop();
if(l != findCounterPart(c)){
std::cout << "Error on line " << l_count << ": Read " << c <<
", expected " << findCounterPart(l) << std::endl;
isError = true;
}
}
}
if (isError){
printErrorLine(x, c_count ,line);
return 0;
}
}
}
if (!S.empty()){
c = S.pop();
std::cout << "Error on line " << l_count << ": Too many " << c << std::endl;
printErrorLine(c_count, c_count , line);
}
else{
std::cout <<"No Errors Found" << std::endl;
}
return 0;
}
Learning to be a software engineer is about breaking problems down into manageable chunks, and here we have a couple of doosies. Lets rephrase your question slightly:
I am getting unexpected characters displayed when diff the output of my program against a file containing output of a previous run. Currently I think this is because of some weird behavior of std::cout.
Well, that might be a reasonable assumption, we can't see your code so we can't know if you're doing anything peculiar.
But it would have to be: std::cout is used, well, all over the place. It just doesn't have this behavior unless your code is deliberately writing a | somewhere.
There are a number of steps we could take to resolve this:
Run the program a 3rd time in the debugger and step through until you have some ideas where the '|' is appearing,
Run the program a 3rd time to the console and observe the output,
View the output using a command like cat, less or more, instead of diff
3 is perhaps the most sensible place to start, since the file is already right there and after that #2 will give us a mk1eyeball check.
What we find is: the | does not appear in the file or the output. It's not coming from your program.
Lets create a couple of .txt files and diff them:
osmith#WOTSIT MINGW64 ~
$ echo -e 'First line\nSecond line' >test1.txt
osmith#WOTSIT MINGW64 ~
$ echo -e 'First line\nFile two line 2' >test2.txt
osmith#WOTSIT MINGW64 ~
$ diff -a -y test1.txt test2.txt
First line First line
Second line | File two line 2
When using the -y switch, between the two columns of output, diff has a line of special characters to indicate lines that changed, were inserted or deleted.

Resources