How to read multiple Numbers from different lines in a file - c

I want to implement a program which tells you on which day the eastern sunday falls on when you type in the year. However I don't want the conventional method with scanf, but rather read the year numbers from an extern text file!
So the text file contains this:
1900
1950
2000
What I want is to save each number in every line in my 'int year' variable once which will be run through a mathematical formular that I will spare you from for now.
So e.g. it reads 1900 so it runs that through my program and after that it starts in the second line and reads 1950 so it runs that through and lastly in the third line 2000.
I already tried something like this but it doesn't work at all:
FILE *fp;
fp = fopen("bla.txt", "r");
while (!feof(fp))
{
fgets(year, 4, fp);
}
the rest of the code btw looks like this (for those who want to see the mathematics..)
int main()
{
int year;
int a;
int b;
int c;
int d;
int e;
int easter_sunday ;
a = year % 19 ;
b = year % 4 ;
c = year % 7 ;
d = (19 * a + 24) %30 ;
e = (2 * b + 4 * c + 6 * d + 5) % 7 ;
easter_sunday = (22 + d + e) ;
if (easter_sunday > 31)
{
printf("Easter Sunday in %d", year);
printf(" is April %d\n", easter_sunday - 31);
}
else
{
printf (" Easter Sunday in %d", year);
printf (" is March %d\n", easter_sunday);
}
fclose(fp);

In fgets function 1st argument must be "string" while you provide "integer".
I made some change in your code and it works properly. Check it and tell me if it is not as per your requirement.
int main()
{
int year;
int a;
int b;
int c;
int d;
int e;
int easter_sunday ;
FILE *fp;
fp = fopen("bla.txt", "r");
while (fscanf(fp, "%d", &year) != EOF ) {
a = year % 19 ;
b = year % 4 ;
c = year % 7 ;
d = (19 * a + 24) %30 ;
e = (2 * b + 4 * c + 6 * d + 5) % 7 ;
easter_sunday = (22 + d + e) ;
if (easter_sunday > 31)
{
printf("Easter Sunday in %d", year);
printf(" is April %d\n", easter_sunday - 31);
}
else
{
printf (" Easter Sunday in %d", year);
printf (" is March %d\n", easter_sunday);
}
}
fclose(fp);
}

Related

How to generate a random mathematical operator

I have an assignment that requires me to make a quiz which generates random math questions. I'm fine with everything but i'm struggling to find a way to randomly choose between the mathematical operators "+" and "-".
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int main(){
int choice = 0;
int lives = 0;
int question = 1;
int a;
int b;
int answer = 0;
int ans = 0;
int correct = 0;
printf("\n Welcome to Maths Tester Pro.");
printf("\n Please Select a difficulty:");
printf("\n 1) Easy");
printf("\n 2) Medium");
printf("\n 3) Hard \n");
scanf("%d%*c",&choice);
switch(choice)
{
case 1:
printf("You have selected Easy mode!");
lives = lives+3;
while ((lives !=0)&&(question !=6)){
if(question !=5){
//Ask Question
printf("\nQuestion %d of 5. You have %d lives remaining", question, lives);
srand(time(NULL));
a = (rand() % (10 - 1 + 1)) + 1; //make the sign random
b = (rand() % (10 - 1 + 1)) + 1;
printf("\n%d + %d = ",a ,b);
scanf("%d", &answer);
ans = a+b;
//If answer is correct
if((a+b) == answer){
printf("Correct!\n");
correct = correct + 1;
}
//If answer is incorrect
else{
printf("Incorrect! The correct answer was %d\n",ans);
lives=lives-1;
}
question = question + 1;
}
In my code I have it written as ans=a+b but I want it to be able to randomly pick either "+" or "-".
The easiest way to go would be to change the sign of b. To do so, simply multiply it by either 1 (keeps positive sign) or -1 (makes it a negative):
b = b * ((rand() - (RAND_MAX / 2)) > 0 ? 1 : -1);
Upon execution, you will randomly get a + b or a + (-b).
Example print of the resulting operator:
printf("%d%s%d = %d\n", a, (b > 0 ? "+" : ""), b, a + b);
Note: as pointed in earlier comments, you may also want to randomize the seed in order to prevent you application to keep providing the "same" random numbers with:
/* Randomize seed (needed once). */
srand(time(NULL));
/* Then make your calls to `rand()`. */
...
I offer this as an example of how to cleanly generate and print the sort of problems that you seem to want.
This produces 20 'sum' and/or 'difference' equations. You can simply suppress printing the total in order to pose the question to the user.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
srand( time( NULL ) );
for( int i = 0; i < 20; i++ ) {
int a = (rand() % 10) + 1; // 1 <= a <= 10
int b = (rand() % 20) - 9; // -9 <= b <= 10
printf( "%d %c %d = %d\n", a, "+-"[b<0], abs( b ), a+b );
}
return 0;
}
1 + 3 = 4
1 - 6 = -5
4 + 10 = 14
8 + 2 = 10
10 + 0 = 10
4 + 4 = 8
8 + 10 = 18
8 + 9 = 17
8 - 2 = 6
8 - 4 = 4
2 + 1 = 3
8 - 5 = 3
2 - 6 = -4
4 + 9 = 13
6 + 6 = 12
5 + 0 = 5
3 + 4 = 7
1 + 0 = 1
9 - 5 = 4
8 + 8 = 16
The keen eyed reader will notice that even "10 + 0" is a reasonable problem. Zero is the identity operator(?) for addition (like 1 being the identity operator(?) for multiplication.)
You're free to adjust the ranges of the terms to suit your questions.
You can use rand() function, which is defined in stdlib. And if you want your program to give you different random numbers every time you run it, you need to put srand(time(NULL)) at the beginning, but for the time function, you need to include time.h library

write a code in c to find how many Fridays fell on the fifth of the month from 1 Jan 1801 to 31 Dec 2000, given 24 March 2002 was a Wednesday?

I was given this question to solve. My code outputs 316 but some suggest 345 is a correct answer. I don't know if my code works properly or not since I use the Sakamoto algorithm to calculate the weekday of a given day, month, and year. Since the actual date for 24 March, 2002 is Sunday instead of Wednesday (0 is Sunday ... 6 is Saturday). I add 3 (as a constant variable) in an algorithm. This is where I am a bit hesitant whether I make the right choice or not. However, I think that a shift does not affect anything so is this supposed to work?? Alternatively, I could set the weekday to Tuesday instead of Friday without any constant.
This is my code:
#include <stdio.h>
#include <math.h>
int howManyDays() {
int sakamoto();
int starting_weekday = 3;
int result = sakamoto(24,3,2002,0);
int constant = starting_weekday - result;
int calculated_year = 1801;
int calculated_month = 1;
int count = 0;
do {
int calculated_weekday = sakamoto(5, calculated_month, calculated_year, constant);
//int calculated_weekday = (calculated_day+constant+day_in_months[calculated_month-1]) % 7;
if (calculated_weekday == 5) {
count += 1;
}
calculated_month += 1;
if (calculated_month == 12) {
calculated_month = 1;
calculated_year += 1;
}
} while(!(calculated_month == 1 && calculated_year == 2001));
return count;
}
int sakamoto(int d, int m, int y, int c) {
int offset[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4}; // 0->Sunday ... 2->Tuesday ... 6->Saturday
y -= m < 3;
return (y + y / 4 - y / 100 + y / 400 + offset[m - 1] + d + c) % 7;
}
int main() {
int a = howManyDays();
printf("result: %d", a);
}
Could anyone confirm whether what I think is correct or completely false??
Thanks in Advance, Hope you have a wonderful time :)
Your months range from 1 to 11. Since you're not counting Fridays in December, your results are off by about 1/12th and indeed 345*11/12 = 316.25.

c segmentation fault, reading large file

I'm trying to read a file and store what it contains, but I'm getting segmentation fault, here is part of my code:
int nnodes;
int main(){
FILE * file = fopen("pub08.in", "r");
int nkeys;
fscanf(file, "%d %d", &nnodes, &nkeys);
long int graphsize = nnodes * nnodes;
long int * graph = malloc(graphsize * sizeof (long int));
for (int i = 0; i < graphsize; i++) {
graph[i] = IN;
}
for (int i = 0; i < nnodes; i++) {
long int a, b, prize;
fscanf(file, "%ld %ld %ld", &a, &b, &prize);
graph[a * nnodes + b] = prize;
graph[b * nnodes + a] = prize;
}
}
the file pub08.in looks like this:
100000 10000
61268 56095 10
40567 20917 17
97937 47973 13
74088 21826 13
62183 30464 11
97793 80708 12
35121 90180 10
77067 97297 17
4657 33995 16
88147 42709 18
95937 25936 19
79853 24452 11
9677 36288 11
91869 48767 15
34585 46478 17
41874 40622 15
13700 19942 18
15660 79277 14
...
Full file is here
The segmentation fault happens, I think, on line:
graph[a * nnodes + b] = prize;
What am I doing wrong?
Here is a list of things you are doing wrong:
Check the return values from fscanf.
Validate a and b to ensure that they are in range.
Check the return value from malloc
As per comment - check the return value from fopen

Printing calendar for specific year and month

I am trying to print out a calendar for a specific year and month but keep getting the same calendar for every month. I tried to also add a statement to see if the year is a leap year to add to the number of days but it made no difference. I am new to c.Please help with any suggestions. Thanks in advance.
void print_month_calendar(int year, int month)
{
int day;
int daycode = ddaycode(year);
int days_in_month[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
char *months[]=
{
" ",
"\n\n\nJanuary",
"\n\n\nFebruary",
"\n\n\nMarch",
"\n\n\nApril",
"\n\n\nMay",
"\n\n\nJune",
"\n\n\nJuly",
"\n\n\nAugust",
"\n\n\nSeptember",
"\n\n\nOctober",
"\n\n\nNovember",
"\n\n\nDecember"
};
printf("%s", months[month]);
printf("\n\nSun Mon Tue Wed Thu Fri Sat\n");
if(( year%4==0 && year%100 !=0) || year%400==0)
days_in_month[2] = 29;
for (day = 1; day <= 1 + daycode * 5; day++)
{
printf(" ");
}
//Print all the dates for the month
for (day = 1; day <= days_in_month[month]; day++)
{
printf("%2d", day);
if ((day + daycode) % 7 > 0)
printf(" ");
else
printf("\n ");
}
}
int ddaycode(int year)
{
int daycode;
int d1, d2, d3;
d1 = (year - 1.)/ 4.0;
d2 = (year - 1.)/ 100.;
d3 = (year - 1.)/ 400.;
daycode = (year + d1 - d2 + d3) %7;
return daycode;
}
You have to know the first weekday in the month. You can use localtime to go to specific date, use mktime to get struct tm data which contains weekday. In addition, you can use strftime to get the month name. Example:
void print_month_calendar(int year, int month)
{
time_t rawtime;
struct tm * timeinfo;
time(&rawtime);
timeinfo = localtime(&rawtime);
timeinfo->tm_year = year - 1900;
timeinfo->tm_mon = month - 1;
timeinfo->tm_mday = 1;
mktime(timeinfo);
//sunday is 1 ... saturday is 7
int weekday = 1 + timeinfo->tm_wday;
int days_in_month[] = { 0, 31,28,31,30,31,30,31,31,30,31,30,31 };
if ((year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0))
days_in_month[2]++;
char monthname[30];
strftime(monthname, sizeof(monthname), "%B", timeinfo);
printf(" %s %d\n", monthname, year);
printf(" Su Mo Tu We Th Fr Sa\n");
int day = 1;
for (int i = 1; i <= 40; i++)
{
if (i < weekday)
{
printf(" ");
}
else
{
printf("%3d ", day);
if (day == days_in_month[month])
break;
day++;
if ((i % 7) == 0)
printf("\n");
}
}
printf("\n");
}
int main()
{
print_month_calendar(2016, 10);
return 0;
}
ideone example
October 2016
Su Mo Tu We Th Fr Sa
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31

Program demonstrating structures does not receive correct input values

This simple program demonstrates the use of structures by determining tomorrow's date. It asks for an input of today's date:
#include <stdlib.h>
#include <stdio.h>
int main ( int argc, char *argv[] )
{
struct date {
int month;
int day;
int year;
}; /* ---------- end of struct date ---------- */
struct date today, tomorrow;
const int daysPerMonth[12] = { 31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31 };
printf ( "Enter today's date (mm dd yyyy): \n" );
scanf ( "%i%i%i", &today.month, &today.day, &today.year );
if ( today.day != daysPerMonth[today.month - 1] ) {
tomorrow.day = today.day + 1;
tomorrow.month = today.month;
tomorrow.year = today.year;
}
else if ( today.month == 12 ) { /* end of year */
tomorrow.day = 1;
tomorrow.month = 1;
tomorrow.year = today.year + 1;
}
else { /* end of month */
tomorrow.day = 1;
tomorrow.month = today.month + 1;
tomorrow.year = today.year;
}
printf ( "Tomorrow's date is %i/%i/%.2i.\n", tomorrow.month,
tomorrow.day, tomorrow.year % 100 );
return EXIT_SUCCESS;
} /* ---------- end of function main ---------- */
When running it, what I got:
Enter today's date (mm dd yyyy):
06 09 2014
Tomorrow's date is 6/1/09.
But when I run gdb and printed out the input values:
(gdb) p today.month
$1 = 6
(gdb) p today.day
$2 = 0
(gdb) p today.year
$3 = 9
I'm confused. Why is the input getting incorrect values like that?
Heh. The %i specifier for scanf means to read in a range of integer formats which is similar to that specified for C integer literals.
When you type a leading 0 it means that what follows are octal digits. Since 9 is not a valid octal digit, then just the value 0 is read. The 9 is left for the following %i, so the three numbers read are 6, 0, 9 , with 2014 remaining in the input stream.
To input in base 10 change the %i to %d, then your program will work.
You read the input as scanf ( "%i%i%i", &today.month, &today.day, &today.year );.
Since you prefix 0 in your input, they are treated as octal and thus lead to the result.
You should use scanf("%d%d%d", ...); instead.

Resources