I think it's obvious I don't understand. How do you tell the computer in C to decide which is the appropriate interest rate and then calculate and display it. This is the best I could come up with and I have to hand this as an assignment tomorrow. I had not clue it would be this difficult.
#include <stdio.h>
int main (void)
{
float time;
float principal;
char response[15];
float rate1, rate2,rate3,rate4;
rate1=.04,rate2=.05,rate3=.06,rate4=.07;
float SimpleInterest1;
float SimpleInterest2;
float SimpleInterest3;
float SimpleInterest4;
SimpleInterest1=principal*time*rate1;
SimpleInterest2=principal*time*rate2;
SimpleInterest1=principal*time*rate3;
SimpleInterest2=principal*time*rate4;
printf("Please enter principal\n");
scanf ("%f",&principal);
printf ("Please enter time\n");
scanf ("%f",&time);
if (principal <= 5000)
{
printf ("%f",&SimpleInterest1);
}
printf ("Do you still want the loan?\n");
scanf ("%s",response);
return 0;
}
As it has been already said: do not forget to ask for principal value using
scanf.
Then, use if-else if-else-statements to know in which interval principal lies.
Then, inside each statement, assign interest to the right value.
Then assign time to the right value (you can scanf it if you have to) before calculating the interest.
Also, check if the interest has to be recomputed each year on the
new debt. If this is the case, then the formula should be
debt = principal * (1 + rate)^time.
You can #include <math.h> to use the pow function that computes the power of a float or a double.
Then just printf("%f", debt);.
Aparté:
Michael Overton's book "Numerical Computing with IEEE Arithmetic" pp.82-86 explains pretty well how to compute a compound interest with a stable algorithm, because the naive way to compute it using pow can involve a loss of accuracy.
First off, these two lines are probably a typo:
SimpleInterest1=principal*time*rate3;
SimpleInterest2=principal*time*rate4;
They should become this:
SimpleInterest3=principal*time*rate3;
SimpleInterest4=principal*time*rate4;
Next, if your asking about i/o (input/output), then here's a basic run through:
You use printf( char *format, ...) to output information.
You use scanf( char *format, ...) to do basic input.
Where format is one of the following (this is the basics):
%s : Argument is expected to be of type char*
%i : Argument is expected to be signed int
%f : Argument is expected to be float (use also for double in printf)
%u : Argument is expected to be unsinged int.
When you use scanf, you should check the return value and clear the input buffer, examples will follow:
void clear_buffer() {
// Note that ch is int not char, this is important
int ch;
while( (ch = getchar()) != EOF && ch != '\n');
}
int answers = 0;
float value = 0.0;
do {
// Scanf returns the recieved number of args that fit the format string
answers = scanf( "%f", &value );
clear_buffer();
if (answers == 0) {
continue;
}
} while (value > -0.1 && value < 0.1);
The above may not work as I mainly work with unsigned integers, but it should provide a good foundation at the very least.
You use if...else if....else to determine the formula to use.
Lastly, you should calculate the SimpleInterest AFTER you get a value for time and principal; the c parser cannot 'see into the future'
Related
I'm trying to create a simple converter that will ask a user to input data n times. The scanf() in the loop ideally should allow user to input a response in the terminal, press enter, then pass an output, then ask again....n times. But the program so far, just asks one time and never allows user to ask again.
There are many posts about scanf in loops I've seen, but I wasn't able to connect my issue with any of them.
I'm new to C, coming from Java.
#include <stdio.h>
double feet(double m);
double lbs(double g);
double f(double c);
//double askInput(int num);
int main()
{
int num, i;
i = 0;
printf("how many?\n");
scanf("%i\n", &num);
for(i = 0; i < num; i++)
{
double input = 0.0;
double output;
char unit = NULL;
printf("num to convert, units to convert?\n");
//scanf("%lf %c\n", &input, unit);
if(input == 0.0 && unit == NULL)
{
//input = askInput(num);
scanf("%lf %c\n", &input, unit);
}
//meters to feet
if(unit == 'm')
{
output = feet(input);
}
}
I've tried a number of things. I've tried using a while loop, I've tried putting scanf in a separate function and then also using if statements. I imagine I am not quite understanding how scanf works.
You have a couple issues here.
You're assigning NULL (of type void*) into a char as well as comparing these values later. Don't do this. If you want to use some sort of canary value you could instead use the character '\0' (or any other non-readily enter-able character).
You've given scanf a parameter that it expects to be a char* as a char. In order for the line scanf("%lf %c\n", &input, unit); to work as intended, you should have an ampersand in front of unit in order to pass a pointer to the local variable unit.
Giving scanf trailing whitespace requires it to read all subsequent whitespace until it can determine a block of whitespace has ended (see man 3 scanf for some more info, but note that any whitespace character in the format string is treated equivalently). In this instance having a newline on the end of your scanf calls will require them to read some amount of whitespace and then a non-whitespace character (see also the accepted answer here: white space in format string of scanf()). Just leave off the \n.
Some of your braces (namely the block for the function main) aren't closed. I'm assuming this is just a function of copying-and-pasting into SO though.
Most of this could be avoided with a stricter compilation command. If you're using gcc with the C99 standard you could try
gcc -Wall -Werror -Wextra -Wshadow -pedantic -std=c99 source_file.c.
First of all, I recommend using the _s functions instead of the regulars (for example printf_s and not printf). Second, I wrote down a version of the code that is working. I noticed that whenever I added some text to scanf_s (for example a \n) the program didn't stop but when I printed it with printf the program stopped.
FYI: For initialization, you need to put a number that the user won't enter - If the user doesn't put a value num won't store 0 but -9.2559631349317831e+61. And you should use || instead of && because you want that num and unit will store a value! :)
Here's my code:
#include <stdio.h>
#include <string.h>
int main()
{
int amount;
printf_s("How many numbers would you like to recive?\n");
scanf_s("%i", &amount);
for (int i = 0; i < amount; ++i)
{
// Initialization of all variables.
double convertedNum;
double rawNum;
char unit[3] = "";
// Getting the variables.
printf_s("Please enter the number that you\'d like to convert and the unit to
convert to.\n");
printf_s("Number: ");
scanf_s("%lf", &rawNum);
printf_s("Units (m/ft): ");
scanf_s("%s", &unit, 3);
// To make sure that we're getting right input & the wanted amount of
// numbers.
if (rawNum == -9.2559631349317831e+61 || unit == "")
{
printf_s("Please enter a number and a unit!");
--i;
}
else if (strcmp(unit, "m") == 0)
{
convertedNum = rawNum * 3.2808399;
printf_s("\n\nAfter convention, the number is %f\n", convertedNum);
}
else if (strcmp(unit, "ft") == 0)
{
convertedNum = rawNum / 3.2808399;
printf_s("\n\nAfter convention, the number is %f\n", convertedNum);
}
}
return 0;
}
This is my code
#include <stdio.h>
int main() {
float percentage;
int sp;
int bp;
percentage = (sp-bp)/bp*100;
scanf("%d %d", &sp, &bp );
printf("%.2f%%", percentage);
return 0;
}
Sample input :
150 85
Sample output :
76.47%
but my output is :
-100.00%
Can someone help me fix this?
First of all, you should really read the values before using them:
scanf("%d %d", &sp, &bp);
percentage = ...
Secondly, this:
percentage = (sp-bp)/bp*100;
Does an integer division, so the rest of the division is totally discarded and you will end up with:
(150 - 85) / 85 == 0
0 * 100 == 0.
You should cast one end of the division to float before doing the operation:
percentage = (sp-bp)/(float)bp * 100;
Correct code:
#include <stdio.h>
int main() {
float percentage;
int sp;
int bp;
scanf("%d %d", &sp, &bp);
percentage = (sp-bp)/(float)bp * 100;
printf("%.2f%%", percentage);
return 0;
}
Explanation will add soon.
Code
#include <stdio.h>
int main()
{
float percentage=0;
int sp=0;
int bp=0;
scanf("%d%d", &sp, &bp );
//printf("\n%d%d", bp,sp);
percentage = (sp-bp)/(float)bp*100;
printf("%.2f%%", percentage);
}
Edit
Explain what i changed
As you scanning two integer with one scanf() function.
use scanf("%d%d", &sp, &bp );
Only remove space between two %d %d.
This white space is useless, because scanf() with %d format specifier consume any number of white space. but if you want to scan with %c use that.
scanf() consumes white space for all specifier except for %c, %n, %[…].
see more info on Jonathan Leffler answer
Initialize all variables like this (Declare and Define)
float percentage=0;
int sp=0;
int bp=0;
Because when we declare a variable inside function this is not initiate and have garbage value. This may cause undefined behavior.see C section
Suppose a situation that scanf() cant work properly and the integers sp and bp values remain with defaults. If we don't initiate them, garbage value remains.
Do declare and define at one time and initiate to zero. see
more on declare define
Add (float) explicit conversion to the division.
(sp-bp)/(float)bp*100;
In C result number of An integer that divides to another integer converted to integer and you lost decimal part because that is truncated.
see this
I have been searching for a few days and I have found only one solution that didn't look perfect to me. Our teacher asked us to create a function that would calculate total lenght of distances in between points provided by user.
My idea was to write code this way, using an array of specific type.
The issue is that, I can't come up with any ideas for how to solve the issue with input: He asked us to make the program end once the user doesn't type anything, so I take it for enter - \n sign.
I could use fgets to get the first variable but:
First, I feel like I don't know any other way beside an array for keeping a long decimal number(in a form of a char array with elements making up the number), that the user could put on the input. I don't know if his script doesn't put some "rofl" number in there.
Second, in this case I think that stripping that array off one X would totally break the total structure of this program. I would rather take both X and Y and accept them as char type, but then the function like atof would probably understand only the X and would stop working after the \n sign.
So Y would be left not given. The accepted input numbers should be of double type. Like:
2 2
3 3
-2 4.5
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
double lenght(struct point *coordinates, int n);
struct point {
double x;
double y;
};
int main()
{
double x,y,TwiceAsBig=3;
int i=0,l=0;
struct point *coordinates;
coordinates = (struct point*)malloc(sizeof(*coordinates)*3);
//allocation of memory for pointtype array with a pointer
while(scanf("%lg %lg",&x,&y)==2)
{
coordinates[i].x=x;
coordinates[i].y=y;
i++;
if(i==TwiceAsBig)
{
coordinates = (struct point*)realloc(coordinates, 2*i*sizeof(*coordinates));
TwiceAsBig=2*TwiceAsBig;
}
}
printf("\n");
for(l;l<i;l++)
{
printf("%lg %lg\n", coordinates[l].x,coordinates[l].y);
}
//checking on the array if the values were loaded correctly
printf("%lg",lenght(coordinates,i));
}
//function for dinstace in between the points
double lenght(struct point*coordinates,int n)
{
int l=0;
for(l;l<n;l++)
{
printf("%lg %lg\n", coordinates[l].x,coordinates[l].y);
}
int pair=0;
double lenght,distance;
for(int AoP;AoP<n-1;AoP++)
{
distance=sqrt(pow(coordinates[pair+1].x-coordinates[pair].x,2)+pow(coordinates[pair+1].y-coordinates[pair].y,2));
pair++;
printf("%lg: ", distance);
lenght=lenght+distance;
}
return lenght;
}
As for your problem, using fgets to read a whole line, and the possibly use sscanf to parse out the two numbers might work.
The problem with using only scanf is that all the numeric format specifiers reads and skips leading white-space automatically, and newline is a white-space character. That means your scanf call in the loop condition will wait until there's some actual non-space characters being input (followed by a newline of course, which leads to the cycle starting over again).
What about using scanf("%[^\n]%*c", test); to read a full string.
Then parsing the result using sscanf?
Something like this:
char* userinput = (char*) malloc(sizeof(char) * 100);
scanf("%[^\n]%*c", userinput);
double a, b;
sscanf(userinput, "%lg %lg", &a, &b);
printf("sum %lg\n", a+b);
With input "-5.5 3.2" the code produces "sum -2.3".
%[^\n]%*c is a "scanset" which tells scanf to read everything excluding '\n' and once it reaches a newline it reads the newline character and disregards it.
You could even use scansets to check the input to some degree by specifying which type of characters you expect to read.
%[0-9 .\\-] // would read digits from 0-9, 'space', '.' and '-'
I am trying to check data type of an user input which can be a int,double, string/char etc. Here is my code:
int main(void)
{
char input[100] = "";
double x;
int num;
char str[20] = "";
int assignments[5] = { 0 };
printf("Pls. provide unput");
fgets(input, 100, stdin);
if (sscanf(input, "%d", &num) == 1)
{
printf("the input is a int.\n");
}
else if (strtod(input, NULL) != 0)
{
printf("the input is a double\n");
}
else if (sscanf(input, "%s", &str) == 1)
{
printf("the input is a string\n");
}
else
{
printf("input not recognized");
}
return 0;
}
but it is not working properly — specially the double part. For any input of double it recognize it as an int.
When you scan char array no need for address "str" instead of "&str", character arrays decay to a pointer.
Now coming to the main issue with why you are having trouble. Remember all integers are also doubles/floats. i.e integers are perfect subset of floats. So if you check for integer/read into int variable first, you will always match any float as float input by user will be truncated to int when reading and hence you will never hit branch checking for double.
The way to fix it is to first test for floating point number.So read input into double, then if it is true you test if it is an integer by casting it to integer and seeing relative difference to see if it is less than some tolerance.
So code that fixes this can be seen below
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
int main()
{
char input[100] = "";
double x;
int num;
char str[20] = "";
int assignment[5] = {0};
double tolerance = 1e-12;
printf("Pls. provide input: ");
fgets(input, 100, stdin);
if (sscanf(input, "%lf", &x) == 1) {
// Is it a number? All integers are also doubles.
num = (int)x; // We cast to int.
if ( fabs(x - num)/x > tolerance ) {
printf("The input is a floating point\n");
} else {
printf("The input is a integer\n");
}
} else if (sscanf(input, "%s", str) == 1) {
// Check if it is string
printf("The input is a string\n");
} else {
// No match error.
printf("input not recognized\n");
}
}
SAMPLE
gcc test.c
Pls. provide input: 3
The input is a integer.
Pls. provide input: 3.3
The input is a floating point.
NOTE You should use something more meaningful like machine precision rather than the tolerance that i show.
No surprises that the code will detect input of a floating point value as an int. For example, given input of 2.3, sscanf()'s %d format will recognise the 2 as an int, and stop when it encounters the decimal point. The decimal point will be there to be read by a subsequent input operation.
Try processing the string in order to check what the string contains. Criteria you could use include looking for non-numeric characters (anything other than digits, decimal points, or sign characters) - if those are found, deem the input to be a string. If only digits and sign characters are found, but no decimal point interpret the string as an int. If digits, sign, and decimal points are found, interpret as a float.
You can also do other techniques, for example, if you want to treat 2.3E32 as a floating point, rather than as a string.
You can tailor the above however you like, depending on your needs.
What ever you do, however, you need to do error checking on every operation (reading, interpreting the string, etc). You are best off assuming the input string contains garbage unless it passes your tests - assuming by default it contains an integer may well get you in trouble with input like 2XYZ.
I am a beginner programmer (about a week) and my simple program keeps crashing. What did I do wrong? It crashes before I even input the amount of hours. Please help.
#include <stdio.h>
#include <stdlib.h>
int hours;
float wage;
float total[2];
int main()
{
printf("How many hours have you worked this week?\n");
fgets(hours, sizeof(hours), stdin);
sscanf(hours,"%d", &wage);
if (hours < 40)
wage = 8.5;
total[0] = hours * wage;
printf("You will earn %d dollars", total[0]);
if (hours >= 40)
wage = 12.75;
total[1] = hours * wage;
printf("You will earn %d dollars", total[1]);
return 0;
}
I think the issue is here:
fgets(hours, sizeof(hours), stdin);
fgets doesn't do formatted input, so this will end up crashing in Cruel and Unusual Ways as it tries to use the integer value hours as a pointer to a buffer that should be read.
To fix this, try this:
scanf("%d", &hours);
You also have a completely unnecessary and malformed scanf on the next line:
sscanf(hours,"%d", &wage);
The syntax for scanf is
scanf(formatting-string, destinations...);
Therefore, it should probably look like this:
scanf("%f", &wage);
You should definitely crank up the warning level on your compiler; I'm amazed that this compiled without giving you a warning explaining that something fishy was going on.
There's also an issue with your formatting specifiers in the printf statements:
printf("You will earn %d dollars", total[0]);
Note that total[0] is a float, not an int, so %d is inappropriate. Try using %f instead.
Hope this helps!
hour is defined int but you are initializing it with fgets which is used for inputting strings.
Use
scanf("%d", &hours);
Also use %f instead of %d in all of your printf statements and so with sscanf otherwise your programs behavior will Undefined.
7.21.6 Formatted input/output functions
If a conversion specification is invalid, the behavior is undefined.282) If any argument is
not the correct type for the corresponding conversion specification, the behavior is
undefined.
http://www.cplusplus.com/reference/cstdio/fgets/
fgets gets a char pointer as first argument... you give a int. Thats why it crashes
fgets expects its first argument to be a pointer to the first element of an array of char, which will hold the input. For example:
char hoursBuf[4]; //room for 3 digits plus 0 terminator
if ( !fgets( hoursBuf, sizeof hoursBuf, stdin ))
{
// error on input; you really want to verify that your library calls
// succeed before moving on.
}
This will save the input as a string, or a sequence of characters; in order to perform calculations with it, you will have to convert it to an integer type using another function like strtol or sscanf.
You could avoid the conversion step by using scanf directly:
if ( scanf( "%d", &hours ) == 1 )
{
...
}
scanf will return the number of successful conversions and assignments; in the case above, it should be 1. If it's 0, then the user typed in something other than a valid integer. However, if they type in something like "12w", scanf will convert and assign the "12" to hours, return 1, and leave the w in the input stream to foul up the next input.
I prefer using strtol because it catches those cases:
char *chk; // will point to the first character not converted
int tmp = (int) strtol( hoursBuf, &chk, 10 );
if ( !isspace( *chk ) && *chk != 0 )
{
// *chk is not whitespace or 0, meaning the user typed an invalid character
fprintf( stderr, "%s is not a valid integer string\n", hoursBuf );
}
else
{
// input was good, so we assign hours:
hours = tmp;
}
I know this is a lot to take in for someone who's been programming for about a week. I/O in C can either be "simple" or "robust"; you don't get both.