C program freezes after scanf input - c

I'm working on a homework assignment to calculate the nth prime number as chosen by the user. I had this working just fine, and fairly quickly, but I decided to add in an error message if the user put in anything greater than 50000. For some reason, that decided not to work, so I took it out. After that, my program freezes once the user inputs which prime number they want.
#include <stdio.h>
int main(void)
{
long int pFactor,test,nthCount,target,result,notPrime;
test=2;
nthCount=0;
printf("Which prime number do you want to know?");
scanf("%li",&target);
while (nthCount<target)
{
for(pFactor=test/2;pFactor>1;pFactor--)
{
notPrime=0;
result=(test%pFactor);
if(result==0)
{
notPrime=1;
break;
}
if(notPrime!=1)
{
nthCount++;
notPrime=0;
test++;
}
}
}
test--;
printf("The %li prime number is %li.\n",target,test);
return 0;
}
I think it's something scanf related, as anything I try to print after that doesn't come out.

for(pFactor=test/2;pFactor>1;pFactor--) // where test = 2
deduces to, pFactor>1 is always false (1>1)
So, the flow never enters the for loop and thus, nthCount always remains 0.
while (nthCount<target) // becomes an infinite loop

Your program is stuck within an infinite loop. Body of the for loop is unreachable for all cases and that causing the while-loop to run for infinite time. Modify your program and debug your program yourself next time.

In such cases (program freezes) you can normally quickly get to the root of the problem by making some observations.
First, find out if it's an infinite loop or some function blocking the program flow. 100% CPU usage is a good indicator for an out-of-control loop and 0% CPU usage is a good indicator that your program is blocking, i.e. is waiting for some event to happen. In your case you could have noted that it's the first: an infinite loop.
Then try to find out where and why this happens. You can for example add debug output at strategic positions in suspected loops. You could have adapted your loop body to this:
while (nthCount<target)
{
/* added debug output: */
printf("%ld, %ld, %ld\n", target, nthCount, pFactor);
for(pFactor=test/2;pFactor>1;pFactor--)
{
/* omitted for the sake of brevity */
}
}
Running this, you would have seen something like this:
$ gcc test.cc && echo 1 | ./a.out | head
Which prime number do you want to know?1
1, 0, 0
1, 0, 1
1, 0, 1
1, 0, 1
1, 0, 1
1, 0, 1
1, 0, 1
1, 0, 1
1, 0, 1
Here you can see that the outer loop is spinning infinitely because the inner loop never executes (the last number is always less or equal to one) and thus the loop condition of the outer loop is never changed (and thus never false). And this is where you can start fixing it.

Related

LLDB - count the number of steps to execute a thread or to execute a function eg. main(), and skip to Xth step

(1)
Is there a way to count the number of steps it takes to execute a function or a thread with LLDB?
As an example,
#include<stdio.h>
int main()
{
printf("\n\n\t\tStudytonight - Best place to learn\n\n\n"); // step count: 1
int number;
int number2;
int number3;
number = 50; // step count: 2 (lldb skips declarations)
number = 60; // step count: 3
/*
Comment comment
*/
if(number < 100) // step count: 4 (lldb skips comments)
printf("Number is less than 100!\n"); // step count: 5
else if(number == 100)
printf("Number is 100!\n");
else
printf("Number is greater than 100!\n");
printf("\n\n\t\t\tCoding is Fun !\n\n\n"); // step count: 6 (the lines that are not executed bec of branching are not counted.)
return 0; // step count: 7
}
The step count is provided in the comments in the code above. And I only count step-overs.
The step count is unique to each execution of the code, and is expected to change if command line arguments and environment variables change and affect the control flow of the program.
If there are loops, each iteration will mean counting the lines in the loop again. So if there are 2 steps per iteration and there are 10 iterations, then there are 20 steps for that loop.
(2)
(Although I only count step-overs, I appreciate answers that also tell me how I can configure to include step-ins when I need them, or exclude them when I don't need them.)
(3)
In addition, is there a way to jump to a specific step in that step count? By this, I think of the jump command and How to skip a couple of lines code with lldb?.
However, what if the code has loops? Say:
for (i = 1; i < 11; ++i)
{
printf("%d ", i);
}
return 0;
}
There are 6 static lines of code (counting all those with only the curly brackets as well). However, the number of steps is probably 21. I wish I could jump to the 10th step, for example. Is it possible with lldb?
Another way to count steps is to write a scripted stepping plan that just keeps pushing new "step in" or "step over" plans till you reach whatever your terminating condition is, and updates some python variable each time an individual step is concluded. For more info on writing scripted thread plans, see:
https://lldb.llvm.org/use/python-reference.html#using-the-python-api-to-create-custom-stepping-logic
and there are several examples of scripted stepping plans here:
https://github.com/llvm/llvm-project/blob/master/lldb/examples/python/scripted_step.py
I'm not quite sure what you mean by "jumping to a specific step". If you mean you just what to stop at that point without having to manually intervene, it would be fairly straightforward to make a scripted stepping plan with whatever end conditions you want (the 10th time you hit line 20, or whatever).
But if you mean "get to that stage in the execution w/o going through the intervening code" that's not a trivial problem. How would lldb know what state was modified along the way to that point? For instance to get to a certain iteration of a loop, lldb would have to know to set the loop counter to whatever value it has at that point, which it has no way of knowing.
Instead of counting steps, and executing a counted number of steps, you can use breakpoints in most cases. For example, in the for loop example, a breakpoint can be configured to stop only under the right conditions.
For these examples, I'll assume the printf is on line 23 of file.c.
To stop part way through the loop, instead of executing a number of next commands, a breakpoint condition can be used to stop only when the loop index i is the desired number:
b file.c:23
breakpoint modify --condition 'i == 5'
The condition expression is a evaluated by lldb, so it can be more complex as needed.
In this case, since the condition is a count, another way of doing this is to set an ignore count on the breakpoint:
b file.c:23
breakpoint modify --ignore-count 5
Note: instead of --condition and --ignore-count, you can alternatively use -c and -i.

Selectively ignoring parts of a randomly generated sequence of numbers (in C)

I have a question that may be hard to understand -- but I will try my best to explain.
I'm programming the Simon Game in C. This implementation specifically read/writes to a hardware DAQ module that has a 4 LED display, and 4 corresponding toggle switches.
As per the rules of the Game, I've seeded and generated a random sequence of numbers between 0 and 3 (sequence length is arbitrarily 5). In the Game, if the player presses the wrong switch (i.e. blue is shown but you press green), the game ends and restarts.
The way I've set up the Game looks like this:
(I haven't included the code for function "blinkLED" here -- it turns the actual LED on/off.)
void runSimon(void){
int sequence[MAX_SEQ_LEN];
int i;
int count = 0;
// Seeds the random number generator.
srand((unsigned)time(NULL));
// Generate the random LED sequence & store it as an array.
for (i = 0; i < MAX_SEQ_LEN; i++){
sequence[i] = (rand() % NUM_LEDS);
}
// The game begins!
while (continueSuperLoop() == TRUE){
// Loop the game while the sequence length is less than the pre-defined maximum (currently it's 5).
while (count < MAX_SEQ_LEN){
for (i = 0; i <= count; i++){
// Blink the first 'count' LEDs in the sequence, one at a time.
blinkLED(sequence[i], 1, ONE_SEC);
//
//
//THE ISSUE SHOULD BE HERE (!)
//
// Monitors whether or not the player has made a mistake...if so, blink the red LED thrice, then restart the game.
if (digitalRead(sequence[ !i ] == SWITCH_ON)){
blinkLED(LED_1_R, 3, HALF_SEC);
Sleep(3 * ONE_SEC);
continue;
}
// Monitors whether or not the correct switch is being pressed -- waits for it to be released
while (digitalRead(sequence[i]) == SWITCH_ON){}
}
count++;
}
// If 'count' is equal to 'MAX_SEQ_LEN', the green LED blinks 3x to indicate the player has won .
if (count == MAX_SEQ_LEN){
blinkLED(LED_0_G, 3, HALF_SEC);
Sleep(3 * ONE_SEC);
}
}
}
Where I indicated an issue, I'm not sure how the "digitalRead(sequence[ ! i ]" behaves; I need this line to read every switch that's not supposed to be pressed.
I don't think the compiler understands what I'm trying to do here, though -- for example, if the first number in the sequence is 3 (representing the 4th LED), I need to specify that every other number (0, 1, 2) and its corresponding switch should not be pressed.
Would a solution be to store the current number in the sequence, having a set of four TRUE/FALSE flags for each LED, and monitoring the three non-current numbers and their corresp. switches to see if they are pressed?
I'm getting quite frustrated with writing this program. I'm pretty new to programming. Any help is appreciated.
I'm not sure I understand the rules of this game correctly but one thing that jumps out instantly is
digitalRead(sequence[ !i ]
I think you want
!digitalRead(sequence[ i ]
Also, you need to fix your game flow. Right now it's:
1. Light LED.
2. Check if user pressed the right button.
You need to wait for some time before checking a switch or wait for ANY switch to be pressed and see if it's the correct one. So something like this:
1. Light LED.
2. Wait for timeout or ANY switch to be pressed.
3. If timeout: error
4. else: check if switch that was pressed is correct.
In C, ! operator is a unary NOT. When applied to an integer i, it is equivalent to if (i == 0) return 1; else return 0;. Then you are using !i as an index for sequence array, so it will be either sequence[0] or sequence[1], and clearly this is not what you want. Also your == is inside of digitalRead call :)
I would suggest explicitly checking for every other button not to be pressed. Like this:
int isOtherPressed = 0;
for (ledId = 0; ledId < NUM_LEDS; ledId++) {
if (ledId != sequence[i] && digitalRead(ledId) == SWITCH_ON) {
isOtherPressed = 1;
}
}
if (isOtherPressed) {
// restart the game
}
However, I'm suspicious about the whole gameplay you have, but maybe it's just because I don't know how digitalRead works. For example, the way you use continue doesn't seem to stop the game. Maybe you meant break?

What is wrong in this C code ? If its a logical error please suggest the right way

int i;
for(i=7;i<6;i--)//loop does not execute
{
printf("*");
}
The above code should print one * but it does nothing. Shouldn'tit run same as for(i=7;i<8;i++) ?
Is this a logical error ? Please help.
A for loop has 3 parts
for( init ; cond ; step )
When the execution reaches the loop,
init is executed.
cond is evaluated.
If false, break the loop
If true, proceed to the next step
Execute the body of the loop.
Do step(in many cases, this is increment/decrement)
Goto step 2
In your case , i is set to 7. Then the condition i<6 is checked. Obviously, 7<6 is false. So the loop never gets executed.
And No.
for(i=7;i<6;i--)
and
for(i=7;i<8;i++)
aren't the same.
Perhaps you wanted to write
for(i=7;i>6;i--) //'>' instead of '<'
in which the loop will execute once.
Let's look at the loop
for( i = 7 ; i < 6 ; i-- )
i is initialized 7, but you have the condition i < 6, but i is 7, and therefor, it does not satisfy the condition of the loop. So, the code does not even go through one iteration of the loop.
Maybe, you meant i > 6
In this loop
for(i=7;i<6;i--)
at first you set i to 7 and then check whether i is less than 6. As i is equal to 7 then it is not less than 6 and the loop iterate never.
If you want that the loop would iterate one time then you should write
for(i=7; i > 6;i--)
Though with these magic numbers the loop looks strange.:) It is not clear what is the intention of the programmer.
int i;
for(i=7;i<6;i--)//loop does not execute
{
printf("*");
}
In first execution of this loop value of "i" is 7
next we have to check the condition "i<6" it is false because 7<6 is false ,then it not give any output
for(i=7;i<8;i++) is different because first "i" value is 7
then it checks condition it is i<8 (7<8) it is true.then it executes once ,after that it increment from 1 (i++),then it checks condition .then it is false because "i" is 8
then it stops execution.

How do I create a "twirly" in a C program task?

Hey guys I have created a program in C that tests all numbers between 1 and 10000 to check if they are perfect using a function that determines whether a number is perfect. Once it finds these it prints them to the user, they are 6, 28, 496 and 8128. After this the program then prints out all the factors of each perfect number to the user. This is all fine. Here is my problem.
The final part of my task asks me to:
"Use a "twirly" to indicate that your program is happily working away. A "twirly" is the following characters printed over the top of each other in the following order: '|' '/' '-' '\'. This has the effect of producing a spinning wheel - ie a "twirly". Hint: to do this you can use \r (instead of \n) in printf to give a carriage return only (instead of a carriage return linefeed). (Note: this may not work on some systems - you do not have to do it this way.)"
I have no idea what a twirly is or how to implement one. My tutor said it has something to do with the sleep and delay functions which I also don't know how to use. Can anyone help me with this last stage, it sucks that all my coding is complete but I can't get this "twirly" thing to work.
if you want to simultaneously perform the task of
Testing the numbers and
Display the twirly on screen
while the process goes on then you better look into using threads. using POSIX threads you can initiate the task on a thread and the other thread will display the twirly to the user on terminal.
#include<stdlib.h>
#include<pthread.h>
int Test();
void Display();
int main(){
// create threads each for both tasks test and Display
//call threads
//wait for Test thread to finish
//terminate display thread after Test thread completes
//exit code
}
Refer chapter 12 for threads
beginning linux programming ebook
Given the program upon which the user is "waiting", I believe the problem as stated and the solutions using sleep() or threads are misguided.
To produce all the perfect numbers below 10,000 using C on a modern personal computer takes about 1/10 of a second. So any device to show the computer is "happily working away" would either never be seen or would significanly intefere with the time it takes to get the job done.
But let's make a working twirly for perfect number search anyway. I've left off printing the factors to keep this simple. Since 10,000 is too low to see the twirly in action, I've upped the limit to 100,000:
#include <stdio.h>
#include <string.h>
int main()
{
const char *twirly = "|/-\\";
for (unsigned x = 1; x <= 100000; x++)
{
unsigned sum = 0;
for (unsigned i = 1; i <= x / 2; i++)
{
if (x % i == 0)
{
sum += i;
}
}
if (sum == x)
{
printf("%d\n", x);
}
printf("%c\r", twirly[x / 2500 % strlen(twirly)]);
}
return 0;
}
No need for sleep() or threads, just key it into the complexity of the problem itself and have it update at reasonable intervals.
Now here's the catch, although the above works, the user will never see a fifth perfect number pop out with a 100,000 limit and even with a 100,000,000 limit, which should produce one more, they'll likely give up as this is a bad (slow) algorithm for finding them. But they'll have a twirly to watch.
i as integer
loop i: 1 to 10000
loop j: 1 to i/2
sum as integer
set sum = 0
if i%j == 0
sum+=j
return sum==i
if i%100 == 0
str as character pointer
set *str = "|/-\\"
set length = 4
print str[p] using "%c\r" as format specifier
Increment p and assign its modulo by len to p

GDB: Force through an if statement

This is the structure of my code
if(someFunction())
{
// Some code
}
where someFunction() evaluates to 0 most of the time
When GDB is at line 1 above, if I do next then // Some code will not be executed.
Is there a way to tell GDB to execute the code inside the if statement?
I can just propose you a workaround. Have a temporary variable int i=0 and then do the if as
if(i==1){
//some code
}
When you reach the desired position with gdb. Set i to 1 using
set i = 1
and then your loop will be executed. Of course after the loop you will have to reset you i if you don't want it executed every time.
You can jump to // Some code after stopping on if statement in gdb, unless // Some code was not optimized out, see 17.2 Continuing at a Different Address. Assuming you stopped on if, you can:
jump +2
0 means false, so it will not entering into if loop, use
if(1)

Resources