C programming. Why does 'this' code work but not 'that' code? - c

Hello I am studying for a test for an intro to C programming class and yesterday I was trying to write this program to print out the even prime numbers between 2 and whatever number the user enters and I spent about 2 hours trying to write it properly and eventually I did it. I have 2 pictures I uploaded below. One of which displays the correct code and the correct output. The other shows one of my first attempts at the problem which didn't work correctly, I went back and made it as similar to the working code as I could without directly copying and pasting everything.
unfortunately new users aren't allowed to post pictures hopefully these links below will work.
This fails, it doesn't print all numbers in range with natural square root:
for (i = 2; i <= x; i++)
{
//non relevant line
a = sqrt(i);
aa = a * a;
if (aa == i);
printf("%d ",i);
}
source: http://i.imgur.com/WGG6n.jpg
While this succeeds, and prints even numbers with natural sqaure root
for (i = 2; i <= x; i++)
{
a = sqrt(i);
aa = a * a;
if (aa == i && ((i/2) *2) == i)
printf("%d ", i);
}
source: http://i.imgur.com/Kpvpq.jpg
Hopefully you can see and read the screen shots I have here. I know that the 'incorrect code' picture does not have the (i/2)*2 == i part but I figured that it would still print just the odd and even numbers, it also has the code to calculate "sqrd" but that shouldn't affect the output. Please correct me if I'm wrong on that last part though.
And Yes I am using Dev-C++ which I've read is kinda crappy of a program but I initally did this on code::blocks and it did the same thing...
Please I would very much appreciate any advice or suggestions as to what I did wrong 2 hours prior to actually getting the darn code to work for me.
Thank you,
Adam

your code in 'that' includes:
if (aa == i);
// ^
printf(...);
[note the ; at the end of the if condition]
Thus, if aa == i - an empty statement happens, and the print always occures, because it is out of the scope of the if statement.
To avoid this issue in the future, you might want to use explicit scoping1 [using {, } after control flow statements] - at least during your first steps of programming the language.
1: spartan programmers will probably hate this statement

Such errors are common. I use "step Over", "Step Into", "Break Points" and "watch window" to debug my program. Using these options, you can execute your program line by line and keep track of the variables used in each line. This way, u'll know which line is not getting executed in the desired way.

Related

Monitor flashing when running a Windows SendInput API

Well, I certainly should go to python since I did several functions of this type, keyboard event and mouse event, but decide to try to learn the windows api.
My goal is to know when button 1 of the mouse is pressed.
I created this file in a very beginner way, it returns in mouseData only 0.
The curious thing is that whenever I run it, it flashes my monitor at short intervals in blinks, but between 1 second with it off. Very strange that, execution is not viable.
Could someone help me understand and try to execute to see if it is only here.
Code:
int main()
{
DWORD mouseData = 0;
MOUSEINPUT tagMouse;
tagMouse.dx = 0;
tagMouse.dy = 0;
tagMouse.mouseData = mouseData;
tagMouse.dwFlags = MOUSEEVENTF_XDOWN;
tagMouse.dwExtraInfo = 0;
INPUT tagInput;
tagInput.type = INPUT_MOUSE;
tagInput.mi = tagMouse;
while (true) {
if (GetAsyncKeyState(VK_DELETE)) break;
SendInput(1, &tagInput, sizeof(INPUT));
printf("KEYWORD: %d\n", mouseData);
Sleep(500);
}
system("pause");
return 0;
}
I can reproduce your reported 'symptoms' - and the effect is really brutal!
Now, while I cannot offer a full explanation, I can offer a fix! You have an uninitialized field in your tagMouse structure (the time member, which is a time-stamp used by the system). Setting this to zero (which tells the system to generate its own time-stamp) fixes the problem. So, just add this line to your other initializer statements:
//...
tagMouse.dwExtraInfo = 0;
tagMouse.time = 0; // Adding this line fixes it!
//...
Note: I, too, would appreciate a fuller explanation; however, an uninitialized field, to me, smells like undefined behaviour! I have tried a variety of other values (i.e. not zero) for the time field but haven't yet found one that works.
The discussion here on devblogs may help. This quote seems relevant:
And who knows what sort of havoc that will create if a program checks
the timestamps and notices that they are either from the future or
have traveled back in time.

Board game functions

I have made a program to a board game. My problem is a function, so that certain fields transport the player back or forward. Apparently the thing I did doesn't work.
int numbers()
{
int maxscore;
int numbers[10];
maxscore = enter();
srand(time(NULL));
int nonumbers[3] = {0, 1, maxscore}; //to initialize the scores there shouldn't be a badfield
numbers[10] = rand() % maxscore + 1;
if(numbers[10] == nonumbers[3])
{
numbers[10] = rand() % maxscore + 1;
}
return numbers;
}
int badfields = numbers();
if(score[i] == badfields)
{
printf("Player %d. goes 5 fields backwards", playershown);
score[i] = score[i] - 5;
printf("This player is now in %d Field", score[i]);
}
Somehow I have to repeat the process of entering the maximum score.
I won't directly answer the "question" because there is no "question" to be answered. As others have pointed out in the comments, you need to be more specific and provide a proper description of your problem. But I can still provide the following feedback:
It seems to me you don't quite understand arrays and their indexing. For example, this line should give you a segmentation fault error, or at the very least make a comparison with an unknown value:
if(numbers[10] == nonumbers[3])
This is because your nonumbers array has 3 elements, and thus they should be addressed as nonumbers[0], nonumbers[1] or nonumbers[2] (or, in general, as Weather Vane put it in the comments, from nonumbers[0] to nonumbers[array_lenght-1]). nonumbers[3] will access an undefined position in memory. Your problem could be related to this.
Note that neither me nor anybody is going to review your entire code
to find the error. As stated above, please be more specific.
Also, are you sure you got rid of all compiler errors? Because further down your code you have an uninitialized variable i. To be sure you got rid of all potentially nasty errors, open the terminal (I'm assuming you are on linux) and use the following command to compile your program:
gcc *.c -Wall -Wextra -o program
Then run it with:
./program

I need a function that ask the user to enter a pin and after 3 wrong attempts, they program terminates

I have to write an ATM program for a class, and i cant figure out how to make a function that will ask the user for a pin and if the pin is entered incorrectly three times the program will display an exit message then terminate.... this is what i have some far. I think my issue is i don't know the correct syntax to handle my issue.
I know i will need a for loop but not sure how exactly to construct it.
void validate_acc(){
int user_acc_try;
printf("Please enter your account number: ");
scanf("%d", &user_acc_try);
if(user_acc_try != account_number){
printf("You entered the wrong account number");
}
else{
printf("");
}
}
void validate_pin(){
int user_pin_try;
printf("Please enter your pin number: ");
scanf("%d", &user_pin_try);
if(user_pin_try != pin){
printf("You entered the wrong pin number.");
}
else{
printf("");
}
}
void validate(){
validate_acc();
validate_pin();
}
Secondly, since i can only post every 90 minutes might as well ask another question, I do not know how to make a function go back to the beginning of my program like for example say after an deposit, what is the logic i would need to use to have a function go back to the beginning of my main function. I know of goto labels, that didnt seem to work when i put it in front of my main function like so...
MAIN:
int main()
i would put goto main; in another function and i would get a.... Main is not defined error. I have read a few different questions on here about labels but cant find anything that helps, if someone could guide me in the right direction, you would be giving me a great deal of relief.
thank you in advance.
It's a good idea to write out a flow chart for things like this if you can't figure out how to do it in code.
Please do not use labels/goto in C. It's a nasty habit and it's not needed.
You know how to use if statements to make a decision; think about how you would use a while loop to try to make the same decision over and over again until something changes. For instance, in pseudo-code (because I don't want to do your work for you)
user_has_not_entered_correct_pin = true
retries_left = 3
while retries_left > 0 and user_has_not_entered_correct_pin:
get pin
if pin_is_not_correct(pin) retries = retries - 1
else user_has_not_entered_correct_pin = false
end while
I am limited on time right now, so I will just post a quick help. I would suggest start researching loops in C. Since this is for a class, the book you are using should have information in it about for loops and while loops, but if not, a simple Google search can help a lot.
With a quick search on Google, this site seemed like a decent site for basic information on loops:
Loops in C
It has links and examples of using a for loop, a while loop, a do...while loop and nested loops which should help you solve your problem.
Edited to add:
In your post you mentioned that you think the problem is that you don't know the syntax that you need. It is for that reason that I pointed you to a location that can help you with the syntax that you need to solve your problem rather than show you directly how to solve the problem. I hope that this helps you not only with this question, but going forward in your class as well.
Keep a count variable like I have did below and check the number of attempts:
I don't see a need for goto here. The same logic can be used for checking pin also.
int i=0;
while(1)
{
if(i>2)
{
printf("Maximum attempts reached\n");
break;
}
printf("Enter the acc_num\n");
scanf("%d", &user_acc_try);
if(acc_num == saved_acc_num)
{
// Do your stuff
}
i++;
}
Return value from validate_pin() int validate_pin(){... return 0; .... return 1;} and test it in the main() or your validate().
int i=0;
int result=0;
while ( (result==0)&&(i<3) ){
result=validate_pin();
i++;
}
Dont use goto, learn to use loops.

how to enter while loop using gdb?

I have a while loop as below.
while (*d++ = *sc++)
As I wish to understand pointers in dept I would like to enter the while loop and understand how the while loop is working with the pointers.
I used step in gdb but it does not go into the while loop completely. Is there any way to get into the while loop and understand the manipulation in every step.
* binds tighter then postfix ++. ++ on the right side will be applied last, so:
while (*d++ = *sc++)
is the same as:
while (*d = *sc)
{
d++;
sc++;
The modification is much better to be traced in gdb.
Update:
Don't code like this OP!
Although it might look cool, and prove you are smart. It's difficult to be parsed by the common human brain and therefore error prone? Which we do not want, do we?
Better go for a more clear alternative like proposed above and let the compiler scramble the code.
Option 1:
Look into the assembly code debugging as suggested by Olaf Dietsche.
Option 2:
Use gcc -S test.c to stop compiler after assembling to see the assembly code of your program. Understanding assembly code might be a little hard. More info here
Option 3:
Rewrite your program to something like
while(1)
{
if(*d++ != *sc++)
{
break;
}
}
So that you can put breakpoints and see the values changing.
An alternative, but identical way to write the code is:
*d = *sc;
while (*d > 0)
{
d++;
sc++;
*d = *sc;
}

C \ UNIX \ strcmp first use is wrong, correct all other times

hey all i wrote some code on microsoft VS which is suppose to compare passwords entered to ones stored in database and return approved or denied...
it worked perfectly good on windows, but after converting to UNIX (using eclipse) a funny thing happend - always, the first call to this function doesnt return the approved value when it should, but calling for the function again with exactly the same params returns approved... as desired.
after debugging i am pretty sure the problem is in the "strcmp", that returns false on the first run and true in all other runs on the exact same parameters.
anyone has an idea on what could be the problem??
an example for a commands:
add jt 111
// adding the password to the DB
login jt 111
denied
login jt 111
approved
void login_helper(char *user, char *password){
int found = 0;
int i;
for (i=0 ; i<space ; i++){
if (strcasecmp(data[i].name,user) == 0) {
found = 1;
if (strcmp(data[i].hash ,Md5FromString(password)) == 0)
{
printf("approved.\n");
break;
}
else {
printf("denied.\n");
break;
}
}
}
if (found == 0) printf("denied.\n");
}
I predict that the call to Md5FromString(password) returns a pointer to a buffer that's no longer valid when the Md5FromString() function returns. That would mean that you're running into undefined behavior, and getting lucky in some cases and unlucky in others.
Post the code to Md5FromString().
I'd really doubt there's any problem in strcmp(). :-)
(There's an excellent book on SW development called "The Pragmatic Programmer", by Andrew Hunt and David Thomas, which has a tip regarding debugging called "'select' is not broken", which ultimately means that it's really unlikely that a basic system function (e.g. select() or strcmp()) is broken.)
Did you try printf'ing the contents of 'data[i].hash' and the value returned by 'Md5FromString(password)' right before strcmp()?
Something like:
char *md5;
...
md5 = Md5FromString(password);
printf("i: %d, hash: %s, md5: %s\n", i, data[i].hash, md5);
if (strcmp(data[i].hash, md5) == 0)
{
...
Also, who allocates memory for function Md5FromString()? Can you send the code for Md5FromString()?
Cheers,
Paulo

Resources