I have to make a program in C that gets a non-defined amount of double values and prints them all increased by a certain percentage based on the number. The program should stop when the user enters a negative value. It all works well when I use a small quantity of numbers, but when the input consists of a larger amount of numbers the program prints just the last ones.
Here's my code:
#include <stdio.h>
int main()
{
double ins=0; //the input
while(ins>=0){
scanf("%lf",&ins);
if(ins<0){break;}
else{
if(ins<500){printf("%.2lf ",ins*1.15);}
else if(ins<=1000){printf("%.2lf ",ins*1.10);}
else {printf("%.2lf ",ins*1.05);}
}
}
return 0;
}
Additional information: Using GCC compiler.
Example of output the program should give for a specific input.
Input:
4003.31 1212.35 3414.31
4257.1 1394.37 1217.28
3602.85 4218.58 4994.8
1133.82 1086.48 2117.43
2253.86 3827.71 2170.16
1161.27 3069.77 1338.08
2791.99 3709.33 180.43
4555.77 318.58 1912.24
158.68 2106.49 4439.56
1247.34 -0.79
Output I should get:
4203.48 1272.97 3585.03 4469.96
1464.09 1278.14 3782.99 4429.51
5244.54 1190.51 1140.80 2223.30
2366.55 4019.10 2278.67 1219.33
3223.26 1404.98 2931.59 3894.80
207.49 4783.56 366.37 2007.85 182.48
2211.81 4661.54 1309.71
What could I do to make the program work correctly not just with small amounts but also with quantities like the above ?
Edit: the output I'm getting with the above input is "1309.71",which is just the last number of the full output I should receive.
Note: You have a simple logic error. Because you are checking ins<500 before ins<=100 you can never hit the ins<=100 case.
Your code and sample data works for me. Can you give a more detailed description of the problem?
Well, I found out the solution. As you guys said that the code was working properly for you I tested it using another command line interface. And now the output is correct, so it seems like the one I was using before (Windows CMD) was deleting outputted information when that information reached a certain limit, maybe a small buffer size or something like that. Thank you for the help guys !!
Related
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.
i have a problem that i have been at for over a day now, and i can not solve this with my skills.
So the problem is as follows. I am trying to get an output from a 4x4 keypad, which would not be a problem but input and output are on the same pins. I know that the 74hc573 should keep the information after LE goes low, but i just can not figure out how to read output from 74hc541 without giving new information to the previous chip, because then the state changes again. At the moment i can only read the keys diagonally, because input and output match in that case.
The schematic of the whole circuit can be seen here:
and the problematic part here:
I have tried many different way in C to make it work, but the best I can do is diagonally from 1 to C because of the shared I/O.
Hope you guys can give a tip and help me understand this.
and my code, it is only the part that should take care of getting the output.
while(1)
{
for(i=0;i<4;i++)
{
P3_7=0;
P3_6=1;
in=((0b11110111>>i)&0b00001111);
//in=0b11110111;
*keypad=in;
*led=in;
P3_7=0;
P3_6=0;
*keypad=0x00;
P3_7=1;
out=*keypad;
P3_7 would be RD and P3_6 would be WR, havent given them proper defines yet
Modified code
while(1)
{
for(i=0;i<4;i++)
{
P3_7=0;
P3_6=1;
in=((0b11110111>>i)&0b00001111);
*keypad=in;
*led=*keypad;
vardelay(100);
P3_7=0;
P3_6=0;
*keypad=0xff;
P3_7=1;
out=(*keypad&0b00001111);
if (in==0b1101&&out==0b1101)
{
P3_7=1;
P3_6=1;
lcd_senddata('5');
}
else if(in==0b1110&&out==0b1101)
{
P3_7=1;
P3_6=1;
lcd_senddata('2');
}
When clicking '5' it prints both 5 and 2. And i am not sure why
The key is being able to control the LE pin. Latch Q1 on, then disable the LE. Scan A1-A4 to test buttons 1, 2, 3 and F. The state Q1-4 shouldn't change during the scan if LE is low. Then enable LE, switch to Q2, disable LE and scan the next row, and so on.
Turns out i was over thinking it, I had to simply write and read from the same address. That is all. a simple code like this, will work
if (*keypad=0b11111101)
{
out=*keypad;
if (out==0b11111110)
lcd_senddata('4');
else if (out==0b11111101)
lcd_senddata('5');
else if (out==0b11111011)
lcd_senddata('6');
else if (out==0b11110111)
lcd_senddata('E');
Here is a C function that segfaults:
void compileShaders(OGL_STATE_T *state) {
// First testing to see if I can access object properly. Correctly outputs:
// nsHandle: 6
state->nsHandle = 6;
printf("nsHandle: %d\n", state->nsHandle);
// Next testing if glCreateProgram() returns proper value. Correctly outputs:
// glCreateProgram: 1
printf("glCreateProgram: %d\n", glCreateProgram());
// Then the program segfaults on the following line according to gdb
state->nsHandle = glCreateProgram();
}
For the record state->nsHandle is of type GLuint and glCreateProgram() returns a GLuint so that shouldn't be my problem.
gdb says that my program segfaults on line 303 which is actually the comment line before that line. I don't know if that actually matters.
Is gdb lying to me? How do I debug this?
EDIT:
Turned off optimizations (-O3) and now it's working. If somebody could explain why that would be great though.
EDIT 2:
For the purpose of the comments, here's a watered down version of the important components:
typedef struct {
GLuint nsHandle;
} OGL_STATE_T;
int main (int argc, char *argv[]) {
OGL_STATE_T _state, *state=&_state;
compileShaders(state);
}
EDIT 3:
Here's a test I did:
int main(int argc, char *argv[]) {
OGL_STATE_T _state, *state=&_state;
// Assign value and try to print it in other function
state->nsHandle = 5;
compileShaders(state);
}
void compileShaders(OGL_STATE_T *state) {
// Test to see if the first call to state is getting optimized out
// Correctly outputs:
// nsHandle (At entry): 5
printf("nsHandle (At entry): %d\n", state->nsHandle);
}
Not sure if that helps anything or if the compiler would actually optimize the value from the main function.
EDIT 4:
Printed out pointer address in main and compileShaders and everything matches. So I'm gonna assume it's segfaulting somewhere else and gdb is lying to me about which line is actually causing it.
This is going to be guesswork based on what you have, but with optimization on this line:
state->nsHandle = 6;
printf("nsHandle: %d\n", state->nsHandle);
is probably optimized to just
printf("nsHandle: 6\n");
So the first access to state is where the segfault is. With optimization on GDB can report odd line numbers for where the issue is because the running code may no longer map cleanly to source code lines as you can see from the example above.
As mentioned in the comments, state is almost certainly not initialized. Some other difference in the optimized code is causing it to point to an invalid memory area whereas the non-optimized code it's pointing somewhere valid.
This might happen if you're doing something with pointers directly that prevents the optimizer from 'seeing' that a given variable is used.
A sanity check would be useful to check that state != 0 but it'll not help if it's non-zero but invalid.
You'd need to post the calling code for anyone to tell you more. However, you asked how to debug it -- I would print (or use GDB to view) the value of state when that function is entered, I imagine it will be vastly different in optimized and non-optimized versions. Then track back to the function call to work out why that's the case.
EDIT
You posted the calling code -- that should be fine. Are you getting warnings when compiling (turn all the warnings on with -Wall). In any case my advice about printing the value of state in different scenarios still stands.
(removed comment about adding & since you edited the question again)
When you optimize your program, there is no more 1:1 mapping between source lines and emmitted code.
Typically, the compiler will reorder the code to be more efficient for your CPU, or will inline function call, etc...
This code is wrong:
*state=_state
It should be:
*state=&_state
Well, you edited your post, so ignore the above fix.
Check for the NULL condition before de-referencing the pointer or reading it. If the values you pass are NULL or if the values stored are NULL then you will hit segfault without performing any checks.
FYI: GDB Can't Lie !
I ended up starting a new thread with more relevant information and somebody found the answer. New thread is here:
GCC: Segmentation fault and debugging program that only crashes when optimized
i was practicing my C Prog Language
and i decided to create a salon with cashier features
it looks messy,
though i'm still learning
posted here: http://pastebin.com/B2XaaCYV
it say runtime error with variable "menu", but i tried to recheck it around 5x and i don't see any error with it.
the code is really simple
like xy[0][1] = default 0 = meaning not yet purchased. its value will be 0/1 only. it will be 1 when you actually purchase it after picking the hairstyle.
then of course
xy[1][i] means price of xy[0][i]
i tried using other techniques like removing of breaks and changing variable name, but still it says runtime error with variable menu
no idea what makes the error. so i wish someone can help me with this
scanf("%1s",&menu);
No! A char isn't a string at all. You want to get a single character, so use either getchar() or scanf("%c",&menu);.
A related error is in your core_return, where you try to read 3 characters into a single character. Also, don't call your main in a sub-routine. Instead return from the sub-routine and put a loop in your main. By the way, 'yes' and 'no' aren't valid. If you want to compare strings, you have to use strcmp:
// returns 1 if the user wants to go again
int another_menu(void)
{
char tmp[20];
printf("Do you want another service?");
for(;;){
scanf("%3s",tmp);
if(strcmp("y",tmp) || strcmp("yes",tmp))
return 0;
else if(strcmp("n",tmp) || strcmp("no",tmp))
return 1;
printf("Please specify either 'no' or 'yes': ");
}
}
Use compiler warnings in order to find your errors quicker (GCC: -Wall -Wextra).
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.