I usually work with C#, so please bear with me. Also, the code was written by someone else.
The code essentially outputs some information to a text file, and for some reason, at midnight, the file was only exported with carriage returns and line separators (ie. no actual data).
After debugging it, I noticed that the debugger breaks on a continue;, but then anything after that line in the FOR loop (in init2) is not being executed.
Due to the complexity of the code, I had to remove most of it. But I've included where all the FOR loops are. I just need to know what the CONTINUE is doing that skips where the "important stuff" is being output.
Any help is appreciated. Thanks.
for ( init1; condition; increment ) {
for ( init2; condition; increment ) {
CODE;
for ( init3; condition; increment ) {
CODE;
if (condition) {
CODE;
}
CODE;
}
if (condition) continue; //Always breaks here
CODE; //Never breaks here
if (condition) { //Never breaks here, so important stuff is not output to file.
for ( init4; condition; increment ) {
fprintf_s(fp, "Output important stuff");
}
fprintf_s(fp, "\n");
}
}
if (statement) { //This code runs and the following is printed.
fprintf_s(fp, "----------------------------------------------------------\n");
}
}
It seems like the problem is your condition inside the if statement. I'm not sure that we can provide you further help if we don't see the actual code.
Related
I have started to use C++ programming language as a complete beginner. With the aim of becoming a better programmer for my STEM degree and with the goal of competitive programming in mind. I have started Functions and Loops in C++ recently and there was a problem I was not sure how to approach.
The probelem: "Write a function to check whether a number is prime"
My Approach:
-> I wanted to implement it on my own so I didn't want to copy paste code online where others have used functions with return type bool.
-> Here is the final version of my code that works:
void prime(int k){
for(int k1=2;k1<k;k++){
if(k%k1==0){
cout<<"int is not prime"<<endl;
break;
}
else{
cout<<"int is prime"<<endl;
break;
}
}
}
->I would then call this in int Main() and get the user to input integers and so on.
-> The above code was due to many trial-and-errors on my part and my thought process was as follows: 1)if i don't include the "break;" statement my code results in an infinite loop 2)I needed a way to stop my code from going toward an infinite loop 3) I remember a topic covered in the functions segment of this website , where we can use it to terminate a loop at will. Thats why i incorporated it into my code to produce the final version
My Question:
Can someone explain how the break; statement is working in the context of my code? I know it produces my desired effect but I still haven't gotten an intuition as to how this would do my work.
Many online resources just cite the break statement as something that does so and so and then gives examples. Without going through the code mechanics. Like how a loop would be going through its conditions and then when it encounters the break; statement what does it do? and as a consequence of that what does it do to help my code?
Any advice would be helpful. I still couldn't wrap my head around this the first time I encountered it.
In your case if k % k1 does not show that the k1 being a factor of the k, the loop is broken after the print statement. If the k % k1 does show that the k1 being a factor of the k, it also breaks out of the loop.
So, either of the break statements leads to the loop termination on the first iteration here. If you test for whether a number is being a prime, it does not work.
In essence, you don't need either of the break statements here. They are mostly forced here. Take a look at the following approach:
#include <iostream>
#include <cmath>
bool prime(unsigned k){
if (k != 2) { // Direct check, so to remain similar to the OP's structure of the code
unsigned up_to = sqrt(k) + 1; // Calculate the limit up to which to check
for (unsigned i = 2; i < up_to; ++i) {
if (k % i == 0) {
std::cout << "Is not prime" << std::endl;
return false;
}
else std::cout << "Checking..." << std::endl;
}
}
std::cout << "Is prime" << std::endl;
return true;
}
// Note, we can check just up to the square root of a k
A note on the behavior of the break
The fact that it breaks out the the closest loop to it - has crucial nature for nested loops (all of them: for, while, and do while):
while (/* condition 1 */) // Outer loop
while (/* condition 2 */) // Inner loop
if (/* condition 3 */) break;
Here if the condition 3 is satisfied, the break will lead to break out of the Inner loop but the Outer loop will still continue to iterate.
For more, you may be interested in "How to exit nested loops?" thread. It addresses your second question.
Analogy... I found it in the last place I looked... like always!
Looking for your keys is the LOOP you are in... when you find them... you BREAK out and move on to another task... like maybe getting into your car...
SO if you are IN your car and know your car is where you left your keys... then you are in the PROCESS of getting prepared to drive away... BUT that process requires keys... THUS you change modes/focus and begin a cyclic process of looking for keys... when found to BREAK that searching process IMMEDIATLY and resume what your were doing.
MANY people would make use of the RETURN instrucion in your code pattern... in place of the break! Both do the same thing... however the RETURN is more descriptive english... and one should be concerned with the programmer behind him... Also a bit of digging might show how one is more efficient than the other...
When running my C++/Qt5 program under gdb I experienced what seems like an impossibility:
while(totalAvailable > (sizeof(quint32)+sizeof(quint16))){
if(nullptr!=c){
// POINT-A
qDebug()<<rct<<"Courier message with ID "<<octomy_message_type_int<<" was received with name "<<c->getName()<<" and "<<bytesAvailable<<" bytes available";
const quint16 bytesSpent=c->dataReceived(*ds, bytesAvailable);
const int left=bytesAvailable-bytesSpent;
totalAvailable-=bytesSpent;
if(left>=0){
if(left>0){
ds->skipRawData(left);
totalAvailable-=left;
}
else{
// POINT-B
qDebug()<<rct<<"LOLBOB";
}
}
else{
qWarning()<<"BAR";
return;
}
}
else{
qWarning()<<"FOO";
return;
}
}
In short, when I step from //POINT-A to //POINT-B everything is as expected, but as soon as I step past //POINT-B debugger jumps up to the first line of the program (while statement). But there are no break or continue or other flow-altering statements in the code. How is this possible?
I have tried rebuilding my code from scratch to eliminate a bogus linkage or similar problems, but the bug is reproducible still.
Any input is welcomed.
At POINT-B, you are inside an else, which is inside an if, which is inside an if. Once this else is done, there is nothing more to do in the whole tree.
Where would you expect the pointer to jump to??
Technically, it would go to the closing bracket two lines behind POINT-B, then to the closing bracket three lines behind POINT-B, and then to closing bracket eight lines behind POINT-B, and then to the closing bracket at the very end. All those do nothing, so they are skipped.
Take a paper and pencil, and diagram the logical flow of this chunk of code.
You will make a surprising discovery that the only statement that could possibly execute, after the statement you marked "POINT B", is the condition at the beginning of the while loop. After executing the "POINT B" statement, there are no more statements to execute in the body of the loop, so execution winds back to the while condition, for the next iteration.
Basically the loop just re-iterates. I believe it is functioning as it is supposed to. From Point-A the control goes like such:
If no.1 (Point-A) -> If no.2 -> Else corresponding to If no.3 -> back to end of If no.2 -> back to end of If no.1 -> back to end of while loop.
As the loop is over, the execution checks the loop's condition, (if it is satisfied) re-iterates, and eventually you reach Point-A again.
while()
{
if() // If no.1
{
// Point-A *****************************
if() // If no.2
{
if() // If no.3
{
}
else()
{
// Point-B *****************
}
}
else
{
}
}
else
{
}
}
To improve debugging and readability, do not keep nesting if blocks or loops - It is very hard to trace the execution.
Look if you write it this equivalent way:
while(totalAvailable > (sizeof(quint32)+sizeof(quint16))){
if(nullptr==c){
qWarning()<<"FOO";
return;
}
// POINT-A
qDebug()<<rct<<"Courier message with ID "<<octomy_message_type_int<<" was received with name "<<c->getName()<<" and "<<bytesAvailable<<" bytes available";
const quint16 bytesSpent=c->dataReceived(*ds, bytesAvailable);
const int left=bytesAvailable-bytesSpent;
totalAvailable-=bytesSpent;
if(left<0){
qWarning()<<"BAR";
return;
}
if(left>0){
ds->skipRawData(left);
totalAvailable-=left;
}
else{
// POINT-B
qDebug()<<rct<<"LOLBOB";
}
}
In this piece of code, in every iteration of while loop, a line is read from a file. The line is something like:
13,4636137,29464742,29464746,995560164
for every number specified in bold, the existence of that number as a key in a std::map is checked in a for loop. If the key exists, then the value is appended to the string. Then the string is written to the file.
If one of keys not exist in the map, then for that line nothing should be written to the file. (bool is_points_in_range)
But in practice, in the cases that the last point (outside of for loop) is not in key list, the program logic performs well.
Why the boolean operator does not change in for loop?
vector<string> res;
ifstream infile;
map<string, string> m;
while(infile.getline(buffer, LINE_BUFFER_LEN))
{
line=string(buffer);
res = SplitBySep(line, ",");
bool is_points_in_range=true;
string geo_file_line;
for (int i=2;i<res.size()-1;i++){
if ( m.find(res[i]) == m.end() ) {
is_points_in_range=false;
break;
} else {
geo_file_line= geo_file_line.append(m[res[i]]).append("^");
}
}
if ( m.find(res[res.size()-1]) == m.end() ) {
is_points_in_range=false;
} else {
geo_file_line= geo_file_line.append(m[res[res.size()-1]]).append("\n");
}
if (is_points_in_range){
fprintf(fp_geo, "%s",geo_file_line.c_str());
}
}
res.size()-1 is extremely dangerous. res.size() is an unsigned type, and subtracting one from it when res.size() is 0 is going to give you a very large unsigned integer due to wraparound.
So your program is essentially undefined when res is unpopulated.
I'm amazed your compiler didn't warn you. Do you have warnings switched off?
It looks like
m.find(res[i]) == m.end()
is never true.
Are you sure that this table is fulled properly? res[i]
It is better to ask that why this conditional statement does not work well?
We know that for obtaining that a key exists in a std::map, we can use:
if ( m.find("f") == m.end() ) {
// not found
} else {
// found
}
as indicated in this question.
But for
map<string, string> m;
this statement does not work well. I dont have any 29464742 key (I am sure), but when I search for this key the else part is executed. Also when I use m.count('29464742') , 1 is returned. I don't know why?
I corrected my code with this conditional statement:
if ( m["f"] == "" ) {
// not found
} else {
// found
}
This works for me and my problem is solved.
#include <iostream>
#include <vector>
using namespace std;
int in;
bool isPrime(int n) {
for (int i = 3; i <= n; i ++) {
if (n%i != 0) {
return false;
}
}
return true;
}
vector<int>* generateVector(int n) {
vector<int> v;
for (int i = 2; i < 20; i ++) {
if (i == n) {
continue;
}
if (isPrime(i+n)) {
v.push_back(i);
}
}
}
int main()
{
while(1) {
cin >> in;
vector<int>* nVectors[21];
for (int i = 1; i <= 20; i ++) {
nVectors[i] = generateVector(i);
} <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
}
}
This some c++ code. And i would like to make a break point just after the for loop(the arrow show the position).
I have found one way to solve it through adding a statement after it then make break point in this statement. But adding a statement without a meaning make not feeling good. So is there a better solution?
I am using GDB for debugging.
PS: I have already known how to set breakpoint in gdb. My intent is to break after the for loop ends, and display what in nVectors. Thanks.
Sorry for all. It's not the issue about the gdb or debugging skill, but there is a bug in my code. So when i print nVectors, nothing was printed. After fixing it, every method you provides works fine. Thanks.
You can use a assembly break point, just need to understand the assembly code of for loop.
gdb <your_bin>
layout split
break *0x80488ad #assmebly code will look like
#0x80488ad jmp 0x8048874 <main+18>
gdb has a command to add break points
there are a couple of ways, but I think the one that might help you is :
(gdb) break filename:linenumber
so for example I want to break at line 10 in main.c
break main.c:10
you might want try a tutorial http://www.yolinux.com/TUTORIALS/GDB-Commands.html
Nope there has to be some statement for the debugger to be able to set breakpoint.
I don't think there is a way to directly do what you want but you can still do it. Set a breakpoint on the last statement of the loop. When the debugger breaks switch the disassembly view and scroll down until you find where you want to place the real breakpoint. This will effective set a breakpoint at a specific address rather than on a line number in a source file.
You can specify the source file and line of the end of the loop, like so, on the gdb command line:
b file.c:123
If you want to go right after the for loop, you'll want to actually set the break for the line of the closing bracket of the while() loop, I believe. But you can try both and see what gives the desired result.
Try to use until command. It is useful to avoid single stepping through a loop. Also from gdb manual:
until always stops your program if it attempts to exit the current
stack frame.
If it was me, I'd set an assembly breakpoint, like the others said. But if you don't want to get into that, there's a simpler way: Since you know the loop count (20), and it is not very big, you can set a breakpoint on the last statement inside the loop (in your case, the only statement inside the loop), with the condition
if (i == 19)
Alternatively, you can set an ignore count:
ignore bnum 19
where bnum is the breakpoint number. This is probably faster, but in your case the difference will be negligible.
See Breakpoints, watchpoints, and catchpoints in the gdb documentation for more information.
I have a simple console application that outputs a menu and waits for user input. After performing the appropriate action, the entire process repeats. The program exits when a specific string is entered. This is implemented with an infinite loop and an early return statement:
int main()
{
while (true)
{
OutputMenu();
string UserChoice;
cin >> UserChoice;
// ...
if (UserChoice == "exit") return 0;
}
}
According to my teacher, it's bad practice to use an infinite loop and hack my way out of it with a return statement. He suggests something like the following:
int main()
{
bool ShouldExit = false;
while (!ShouldExit)
{
OutputMenu();
string UserChoice;
cin >> UserChoice;
// ...
if (UserChoice == "exit") ShouldExit = true;
}
return 0;
}
Is it really a bad idea to use an infinite loop and an early return statement?
If so, is there a technical reason or is it just bad practice?
This might be one of those rare cases where do...while is appropriate. I avoid adding extra boolean state variables unless they genuinely make the code clearer.
int main()
{
string UserChoice;
do
{
OutputMenu();
cin >> UserChoice;
// ...
} while (UserChoice != "exit");
}
However, for a user input loop I would usually make a function that returns whether or not the input was successful. As it stands the code could easily end in an infinite loop if cin closes.
E.g.
bool GetNonExitInput( std::istream& in, std::string& s )
{
OutputMenu();
in >> s;
return in.good() && s != "exit";
}
int main()
{
std::string UserChoice;
while (GetNonExitInput(std::cin, UserChoice))
{
// ...
}
}
Really either is fine, but you need to do what your professor wants. You'll find it is the same in industry as well. Some companies may have a coding standard that dictates curly braces go on a new line, while others want them to start on the line that begins the block. There is no real reason to prefer one over the other, so it is best to just go with what the lead wants.
The only difference between these two approaches is that in the second approach you can still do something after you exit the while loop, while in the first approach, you're returning from the function itself; you can do nothing after the while.
However, I would suggest this simple code : instead of maintaining a variable, you can also use break like this:
while (true)
{
//your code
if (UserChoice == "exit")
break;
//your code
}
The variable ShouldExit is not needed anymore!
Depends on the language. If you're writing in C, then the "one entry, one exit" philosophy makes sense -- you want one place where you're cleaning up resources used by a function so that you don't have a chance of forgetting later. If you're in C++, then you should be using RAII for cleanup anyway, in which case I completely disagree with your teacher. Use returns as needed in order to make the code as clear as possible.
(Though I would use for (;;) instead of while (true) in C++ to generate the infinite loop)
With the controlled variable you would be able to handle exit conditions (code after the while) before exiting the function.
In my opinion both ways are fine, but the second one is "prettier".
In programing it is important to write the code in the easiest way you can think of, and make it simple for other programmers to understand your code if you'll be replaced or for any other reason.
There is no complexity issue involved with your two codes so they are both fine as I said, but the think I don't like about the first code is the use of 'return' statment without any real need of 'return' statment here.
There is another way writing this code, better then your way (in my opinion), but not better as your teacher's one.
int main()
{
bool ShouldExit = false;
while ( true )
{
OutputMenu();
string UserChoice;
cin >> UserChoice;
// ...
if (UserChoice == "exit") break;
}
}
Another main reason why I don't like your first code and my code above is because of the use of infinite loop, when you make yourself used to infinite loops it is just a matter of time until you will make your more complicated programs with major bugs in it.
Again - all of the things I wrote are in my opinion only and not gospel truth.
Rotem
Technically, there's not much in it, as long as there's no code you're skipping over via the use of the return.
However, your teacher's suggestion is more readable, if only because of the obvious meaning of "ShouldExit".
I think what your teacher means that the exit condition can easily maintained. This because of code cleanup after the while loop. If you will do a hard return then everything after the while loop will not be executed. This can prevented by using a break instead of return.
int main()
{
//create a file
while (true)
{
OutputMenu();
string UserChoice;
cin >> UserChoice;
//write UserChoice to file
// ...
if (UserChoice == "exit") return 0;
}
//close file
}
//close file will then not be executed!
The break statement is specifically for exiting loops.
I would usually prefer what your teacher suggested, simply because it's easier to read and understand what are the conditions to stop the loop.
If you have an infinite loop with a return statement it's a little bit more difficult for someone who didn't write the code to go through the code and figure out when the program will hit a return statement.
Also I usually don't like early returns in general because it's easy for someone maintaining the code to introduce bugs, for example:
int main()
{
// code added by some other programmer:
importantInitialization();
while (true)
{
OutputMenu();
// code added by some other programmer:
Something *st = new Something();
string UserChoice;
cin >> UserChoice;
// ...
if (UserChoice == "a") runA();
else if (UserChoice == "b") runB();
else if (UserChoice == "c") runC();
else if (UserChoice == "d") runD();
else if (UserChoice == "exit") return 0;
else if (UserChoice == "help") showHelp();
// code added by some other programmer:
delete st; // this would not run on the last loop
}
// code added by some other programmer:
importantCleanUp(); // this would never run
}
of course that in this particular case it's easy to see the problems, but when maintaining a more complicated function you can see how an early return statement might make it even more prone to lack-of-attention bugs like this.
I think the while(true) with break is best for a few reasons. Introducing a variable to store the exit condition is error prone, more variables means more can go wrong. Also the break statement is meant specifically for breaking out of loops. Lastly, contrary to for(;;), while(true) is clean, readable, and concise, where for(;;) is trying to be clever for no good reason.
For an added point, to enhance readability and comprehension put the exit condition(s) nearest to the top of the loop as possible:
while (true) {
OutputMenu();
string UserChoice;
cin >> UserChoice;
if (UserChoice == "exit")
break;
// process other options here
}
A routine which uses a local flag is, in terms of state analysis, equivalent to the same code, copied out twice, with one copy corresponding to the flag being true, and the other copy being equivalent to the flag being false, and any code which changes the state of the flag jumping between them. If there are n flags, the equivalent would be 2^n copies of the code (though if some flags are mutually exclusive, some of those may be unreachable and irrelevant).
While there are certainly times that flags are the most practical way to do things, they add complexity to the code. When the complexity is really necessary, flags may be the cleanest way to provide it. When there's a clean and practical way to write code which avoids the flags, one should do so. There are certainly times when it may be unclear whether it's better to use or avoid a flag (e.g.
flag = condition_which_must_be_tested_here();
action_which_will_disturb_the_condition();
if (flag)
do_something();
else
do_something_else();
versus
if (condition_which_must_be_tested_here())
{
action_which_will_disturb_the_condition();
do_something();
}
else
{
action_which_will_disturb_the_condition();
do_something_else();
}
but in cases where no code can be written without a flag and without having to duplicate anything, such a version is generally preferable.
I'm philosophically opposed to while(true). It means "loop forever" and you never really want to loop forever.
On the other hand I'm also philosophically opposed to boolean variables that merely record state that can be found out in other ways. There's a bug in waiting in that it may not always be correctly synchronised with the state it is supposed to reflect. In this case, I'd prefer code like:
int main()
{
string UserChoice = "not started"; // or empty string
while (UserChoice != "exit")
{
OutputMenu();
string UserChoice;
cin >> UserChoice;
// ...
}
return 0;
}