Ok, so I have to write a function that uses pointers to convert days into years, weeks, and days. Here is the function.
int convertTime(int days, int *y, int *w, int *d){
if (days < 0 || y == NULL || w == NULL || d == NULL){
printf("An error has occured\n");
return 1;
}else{
*y = days / 365;
*w = (days % 365) / 7;
*d = ((days % 365) / 7) % 7)
return 0;
}
}
and here is the part in the main function where I am calling it.
// Tests convertTime
int days = 1000;
int y2 = 0, w2 = 0, d2 = 0;
int *y = NULL, *w = NULL, *d = NULL;
y = &y2, w = &w2, d = &d2;
convertTime(days, y, w, d);
printf("Expected output: 2 years, 38 weeks, 4 days\n");
printf("Actual output: %d years, %d, weeks, %d days\n");
and it prints out
Expected output: 2 years, 38 weeks, 4 days
Actual output: -127184896 years, -132560896, weeks, -135499072 days
You forgot to pass your variables to printf. Fix the last line like this:
printf("Actual output: %d years, %d, weeks, %d days\n", y2, w2, d2);
As stated in the other answer you need to pass in the values to the printf.
Also you need to check the return value for convertTime
Related
I'm stuck on an assignment for C where I have to convert a Julian Date that is input by the user and convert it to Gregorian. When I run it and I enter a number for the Julian date all it prints out is 1, 0, -12 for the month, day and year. How to fix? I also don't completely understand pointers so maybe that is the problem?
#include <stdio.h>
#include <math.h>
void getDateFromJulian(double jd, int *month, int *day, int *year);
double getDoubleFromUser(char* msg);
int main() {
double jd = 0;
int month, day, year;
jd = getDoubleFromUser("Enter a valid Julian Day: ");
if (jd != -999.0) {
getDateFromJulian(jd, &month, &day, &year);
printf("Month, day, year is: %d, %d, %d \n", month, day, year);
}
return;
}
double getDoubleFromUser(char* msg){
int input;
int term;
//check for valid number
printf("Enter Julian Day: \n");
scanf_s("%1f%c");
if (scanf_s("%1f%c", &input, &term) != 2) {
if (term >= 0 * 41 && term <= 0 * (int)7) {
printf("That's not a valid number!\n");
return -999.0;
}
}
}
void getDateFromJulian(double jd, int *month, int *day, int *year) {
int A, B, C, D, E, alpha;
double Z, F;
int JD = 0;
F = modf(JD, &Z);
if (Z < 2299161) {
A = Z;
}
if (Z >= 2299161) {
alpha = (int)((Z - 1867216.25) / 36524.25);
A = Z + 1 + alpha - (int)(alpha / 4);
}
B = A + 1524;
C = (int)((B - 122.1) / 365.25);
D = (int)(365.25 * C);
E = (int)((B - D) / 30.6001);
day = B - D - (int)(30.6001 * E) + 0.5;
if (E < 14) {
month = E - 1;
}
if (E = 14 || 15) {
month = E - 13;
}
if (month > 2) {
year = C - 4716;
}
if (month = 1 || 2) {
year = C - 5715;
}
return;
}
When you assign to the day, month, or year you should do it as follows:
day[0] = B - D - (int)(30.6001 * E) + 0.5;
month[0] = E - 1;
and so on. Basically, you have to assign to the first element of the pointer (array) which is sometimes a little bit clearer than using an asterisk, which you left out.
The program effectively wasn't doing anything because the output values were essentially set to gibberish.
In addition to assigning integers to pointers (month = newVal; for example), some of your conditional tests are always true.
if (E = 14 || 15) {
month = newVal;
newVal = E - 13;
}
This assigns the value of 14 || 15 (which is 1) to E, and then tests that E is non-zero, which of course, it always is.
This test (and the other one like it) should be:
if (E == 14 || E == 15) {
*month = newVal;
newVal = E - 13;
}
Note that the newVal integer is assigned to the integer that is pointed to by month (by using *month), and not the actual pointer variable month. This remedy should be applied to assignments to the day and year pointers also.
I've write the code to print the one month calendar by input of integer month and integer year. But I want to input the month by characters, first three letters of the month word like Jan for January and Feb For February.As Shown in the picture the month is entered by characters. Here is the Image. So please change the code, so I can input the month in character.Thanks
#include <stdio.h>
int isLeapYear(int y); /* True if leap year */
int leapYears(int y); /* The number of leap year */
int todayOf(int y, int m, int d); /* The number of days since the beginning
of the year */
long days(int y, int m, int d); /* Total number of days */
void calendar(int y, int m); /* display calendar at m y */
int main(void) {
int year, month;
printf("Enter the month and year: ");
scanf("%d %d", &month, &year);
calendar(year, month);
return 0;
}
int isLeapYear(int y) /* True if leap year */
{
return(y % 400 == 0) || ((y % 4 == 0) && (y % 100 != 0));
}
int leapYears(int y) /* The number of leap year */
{
return y / 4 - y / 100 + y / 400;
}
int todayOf(int y, int m, int d) /* The number of days since the beginning
of the year */
{
static int DayOfMonth[] =
{ -1/*dummy*/,0,31,59,90,120,151,181,212,243,273,304,334 };
return DayOfMonth[m] + d + ((m>2 && isLeapYear(y)) ? 1 : 0);
}
long days(int y, int m, int d) /* Total number of days */
{
int lastYear;
lastYear = y - 1;
return 365Q * lastYear + leapYears(lastYear) + todayOf(y, m, d);
}
void calendar(int y, int m) /* display calendar at m y */
{
const char *NameOfMonth[] = { NULL/*dummp*/,
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"
};
char Week[] = "Su Mo Tu We Th Fr Sa";
int DayOfMonth[] =
{ -1/*dummy*/,31,28,31,30,31,30,31,31,30,31,30,31 };
int weekOfTopDay;
int i, day;
weekOfTopDay = days(y, m, 1) % 7;
if (isLeapYear(y))
DayOfMonth[2] = 29;
printf("\n %s %d\n%s\n", NameOfMonth[m], y, Week);
for (i = 0; i<weekOfTopDay; i++)
printf(" ");
for (i = weekOfTopDay, day = 1; day <= DayOfMonth[m]; i++, day++) {
printf("%2d ", day);
if (i % 7 == 6)
printf("\n");
}
printf("\n");
}
There are many way to do this. They usually involve taking the input string and looking up in some table.
An efficient way is to compute a hash based on the string input rather than do up to 12 string compares. Use the hash to look that month name and see if it matches. The hash below requires ASCII encoding for the month names. char may be signed or unsigned.
Of course if the month names change (another language?), the specific values and hash method below need adjustment.
// Assume month is any 3 ASCII characters (either case)
int month2int_chux(const char *month) {
if (month[0] && month[1] && month[2]) {
unsigned m0 = month[0] | 0x20;
unsigned m1 = month[1] | 0x20;
unsigned m2 = month[2] | 0x20;
unsigned m = (14 * m2) ^ (47 * m1); // magic computation does not use m0.
m %= 13;
const unsigned char hash[] = { 9, 11, 5, 12, 0, 7, 2, 1, 3, 4, 8, 10, 6 };
m = hash[m % 13u];
if (m && (NameOfMonth[m][0] | 0x20) == m0 &&
NameOfMonth[m][1] == m1 && NameOfMonth[m][2] == m2) {
return m;
}
}
return 0;
}
I am getting an error when compiling this code. Z is the final count of coins needed to make change with aim being to use minimum number of coins. I defined int Z = 0 near the top. I've tried adding int z again and changing type to f in print statement but no luck.
Here's the error:
error: format specifies type 'int' but the argument has type '<dependent type>' [-Werror,-Wformat]
greedy.c:77:16: error: use of undeclared identifier 'z'
printf("%i\n", z);
Here is my code. I am a beginner so any suggestions or corrections would be welcome.
#include <stdio.h>
#include <cs50.h>
#include <math.h>
int main(void)
{
//prompt user for amount of change owed
float f;
int num; //amount of change
do
{
printf("O hai! How much change is owed?:\n");
f = get_float();
}
while (f < 0); //verify input is positive
num = round(f * 100); //rounds float
//commence making change
do{
int c, e, i, j;
int z = 0; //z = coins
if (num % 25 == 0) // verifies that num is divisible by 25 so only 25c coins necessary
{
z = (num/25) + z; // updates final number of 25c coins
}
else if (num % 25 > 0)
{
i = num / 25;
j = num % 25;
}
else if ((num / 25 < 0) || (num >=10 && num < 25)) //this means that f is less than 25 cents so has to be divided by 10 cent coins
{
num = c;
c = j + c; //add remainder of num to the number to start with
}
if (c % 10 == 0) // c is less than 25c but divisible by 10c pieces
{
z = (c / 10) + z; //d is the final number of 10c coins
}
else if (c /10 < 1) //this means it's less than 10c
{
c = e; // Then c must be less than 10c
}
else if (e % 5 == 0) // divisible by 5c pieces
{
z = (e / 5) + z; // g is the number of 5 cent pieces
}
else if (e % 5 < 0)
{
z = (e / 1) + z; //h is the number of pennies
}
}
while (num > 0); //num is rounded float
printf("%i\n", z);
}
Firstly, I suggest you should format your code properly with indents.
Then, the cause of error is that z is declared inside the block associated to do loop and printf("%i\n", z); is out of its scope.
To get rid of this error, declare z at the place where visible from the printf() call -- for example, just before the do loop.
Note that declaring int Z = 0 won't work because identifiers' names are case-sensitive in C.
Like already said, you are declaring z inside the do-while loop, so it's visible only inside the loop.
You should declare it before the loop starts, so you can use it after the loop ends as well. Like this:
int z = 0; //z = coins
do{
***YOUR CODE***
} while();
Here is my attempt at computing the GCD of two input numbers:
int rep;
do{
system ("cls");
int a, b, gcd=2, e, d;
cin >> a >> b;
if(a % b != 0 || b % a != 0){
do{
gcd = gcd + 1;
d = a % gcd;
e = b % gcd;
} while(d==0 && e==0);
cout << gcd-1;
}else if(a == 1 || b == 1){
gcd=1;
cout << gcd;
}else if(a >= b){
gcd = a;
cout << gcd;
}else if(b >= a){
gcd = b;
cout << gcd;
}
cin >> rep;
} while(rep == 1);
If I input 8 and 24, it gives me 2 as the answer. Can anyone spot the problem in my code?
The problem is that the algorithm gives up the first time a test GCD fails. In most cases, finding the greatest means going past some values that do not work. In this case, working up to 8 means getting past 3, 5 and 7.
8 % 24 == 8. So the do loop runs at least once. gcd becomes 3 and is tested, but does not divide evenly into 8, so the while condition evaluates to false. Then 3 - 1 (2) is streamed to cout. It's not the correct GCD, though.
You could revise your algorithm to start with the lesser of the 2 inputs, and work downward until there is a success (8 here), and then a failure (7 here).
The meat of the GCD algorithm here is only 3 lines, the rest is devoted to preventing silliness.
#include <stdio.h>
unsigned GCD(unsigned x, unsigned y) {
unsigned z;
if (x < y) {
z = x; // swap
x = y;
y = z;
}
if (y == 0)
return 0;
while (z = x % y) { // perform the GCD with implicit 0 test
x = y;
y = z;
}
return y;
}
int main(void)
{
printf("GCD of %u, %u = %u\n", 1, 0, GCD(1, 0)); // billed as C
printf("GCD of %u, %u = %u\n", 0, 1, GCD(0, 1));
printf("GCD of %u, %u = %u\n", 1, 1, GCD(1, 1));
printf("GCD of %u, %u = %u\n", 8, 24, GCD(8, 24));
return 0;
}
Program output:
GCD of 1, 0 = 0
GCD of 0, 1 = 0
GCD of 1, 1 = 1
GCD of 8, 24 = 8
I'm doing this assignment for college in C, should be fairly simple, but a loop in it doesn't seem to terminate so the code won't work properly; even if I put in an i value to limit the amount of times it loops. Tried it with a for loop too, still gets stuck.
The code is supposed to take in values of coefficients and try to work out a root for a cubic equation by finding the midpoint between two large values and trying that out to see if it gets 0, if it doesn't, it should change one of the limits to the midpoint value. Here's the relevant code:
int main (void)
{
int i, u=1000, l=-1000;
float a, b, c, d, mid, y;
scanf(" %f %f %f %f", &a, &b, &c, &d);
while (abs(u - l) > 0.001 && i < 10)
{
mid= (u + l)/2;
y = a * pow(mid, 3) + b* pow(mid, 2) + c * mid + d;
if(y == 0) break;
else if(y < 0) l = mid;
else u = mid;
i++;
}
printf("\nThere is a root at: x = %.3f\n", mid);
}
Any help would be appreciated, thanks!
edit: Oh my god I'm an idiot. Always the small things. The code still isn't working but at least it's not stuck anymore, thanks guys!
You declared i, but did not initialize it, so it is set to whatever random value was left in memory.
For this example, lets say that value was -12,345.
Then i can be incremented over 12,000 times before it is greater than 10!
Your loop will run when i is incremented 12,355 times, and its value becomes 10, and the test i < 10 finally fails.
To fix this, initialize i = 0:
int i=0;
2 things. Initialize i to 0. this will ensure it terminates after 10 loops.
More important for your problem though, you have declared u and l as integers, I think you need to declare them as floats.
You need to initialize i: int i = 0;
This should work for you! You need to initialize i.
#include <stdio.h>
#include <math.h>
int main (void)
{
int i = 0, u = 1000, l =- 1000;
float a, b, c, d, mid, y;
scanf(" %f %f %f %f", &a, &b, &c, &d);
while (abs(u-l)>0.001 && i<10)
{
mid = (u + l)/2;
y = a*pow(mid,3) + b* pow(mid,2) + c*mid + d;
if(y == 0)
break;
else if(y<0)
l = mid;
else
u = mid;
i++;
}
printf("\nThere is a root at: x = %.3f\n", mid);
}
If you make u and l be floats then your while-loop terminates without i. Before that, abs(u-l) where u-l are ints will only terminate if a root is at zero. You also need to use fabs() instead of abs():
int main (void)
{
float u=1000.0, l=-1000.0;
float a, b, c, d, mid, y;
scanf(" %f %f %f %f", &a, &b, &c, &d);
while (fabs(u - l) > 0.001)
{
mid= (u + l)/2.0;
y = a * pow(mid, 3) + b* pow(mid, 2) + c * mid + d;
if(y == 0) break;
else if(y < 0) l = mid;
else u = mid;
}
printf("\nThere is a root at: x = %.3f\n", mid);
}
Seems like you still have something wrong in the bisection algorithm condition when you reset l and u to mid. I'm attaching a fixed version, and I used different variable names (sorry) to keep my head clear:
#define NMAX 1000
#define TOL 0.00001
int sign( float x ) {
if (x > 0.0) return 1;
if (x < 0.0) return -1;
return 0;
}
int main (void)
{
int n=0;
float fa, fc, b=1000.0, a=-1000.0;
float p3,p2,p1,p0,c;
scanf(" %f %f %f %f", &p3, &p2, &p1, &p0);
while(n<NMAX)
{
c = (a + b)/2.0;
fc = p3*pow(c, 3) + p2*pow(c, 2) + p1*c + p0;
if(fc == 0.0 || (b-a)/2.0 < TOL ) break;
fa = p3*pow(a, 3) + p2*pow(a, 2) + p1*a + p0;
if( sign(fc) == sign(fa) )
a = c;
else
b = c;
n++;
}
if(n==NMAX) {
printf("Method failed.\n");
}
else {
printf("\nThere is a root at: x = %.3f\n", c);
}
}