[SOLVED] Tried to write something "serious" and have failed once again
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Distribution: Currently: OpenMandriva. Previously: openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,881
Original Poster
Rep:
I've been re-reading the chapter about structures in the C book I downloaded, and I have some questions about the example below from it. I want to stress that the code below is exactly how it is written in the book, and thus is *not* my own code. Basically, the code below when run will ask you to enter a date, then based on the date you enter it will display the date for the next day. It doesn't seem to compile with treating warnings as errors, but should if you don't use the relevant arguments to compile it - again, it's not my code.
The first question is that; in the main function, is the following line (the very first line in the CODE block directly below) the prototype for the "dateUpdate" function? Because you'll note what as far as I can tell is the call to the same function below that, I think?
Code:
struct date dateUpdate (struct date today);
...
nextDay = dateUpdate (thisDay);
Because I've been getting quite confused trying to follow the code below. Also, is "thisDay", "nextDay", "today" and "d" the "date" structure's variables as defined in the code below?
Here's the whole code;
Code:
#include <stdio.h>
#include <stdbool.h>
struct date {
int month;
int day;
int year;
};
// Function to calculate tomorrow's date
struct date dateUpdate (struct date today) {
struct date tomorrow;
int numberOfDays (struct date d);
if ( today.day != numberOfDays (today) ) {
tomorrow.day = today.day + 1;
tomorrow.month = today.month;
tomorrow.year = today.year;
}
else if ( today.month == 12 ) {
tomorrow.day = 1;
tomorrow.month = 1;
tomorrow.year = today.year + 1;
}
else {
tomorrow.day = 1;
tomorrow.month = today.month + 1;
tomorrow.year = today.year;
}
return tomorrow;
}
// Function to find the number of days in a month
int numberOfDays (struct date d) {
int days;
bool isLeapYear (struct date d);
const int daysPerMonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if ( isLeapYear && d.month ==2 )
days = 29;
else
days = daysPerMonth[d.month - 1];
return days;
}
// Function to determine if it's a leap year
bool isLeapYear (struct date d) {
bool leapYearFlag;
if ( (d.year % 4 == 0 && d.year % 100 != 0) || d.year % 400 == 0 )
leapYearFlag = true;
else
leapYearFlag = false;
return leapYearFlag;
}
int main(void) {
struct date dateUpdate (struct date today);
struct date thisDay, nextDay;
printf ("Enter today's date (mm dd yyyy): ");
scanf ("%i%i%i", &thisDay.month, &thisDay.day, &thisDay.year);
nextDay = dateUpdate (thisDay);
printf ("Tomorrow's date is: %i/%i/%.2i.\n", nextDay.month, nextDay.day, nextDay.year % 100);
return 0;
}
Sorry if the formatting is a little out of whack, kwrite for KDE 5 keeps messing up the formatting when copying and pasting.
Distribution: Currently: OpenMandriva. Previously: openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,881
Original Poster
Rep:
I mean, in the main function below (for the same code above), it mentions the dateUpdate() function twice; is what's highlighted in bold below the prototype for the dateUpdate function? And where the dateUpdate() function is mentioned below that, is the actual call to call the dateUpdate() function?
Code:
int main(void) {
struct date dateUpdate (struct date today);
struct date thisDay, nextDay;
printf ("Enter today's date (mm dd yyyy): ");
scanf ("%i%i%i", &thisDay.month, &thisDay.day, &thisDay.year);
nextDay = dateUpdate (thisDay);
printf ("Tomorrow's date is: %i/%i/%.2i.\n", nextDay.month, nextDay.day, nextDay.year % 100);
return 0;
}
And where it says struct date thisDay, nextDay; Is "thisDay" and "nextDay" the variables for the "date" structure?
Distribution: Currently: OpenMandriva. Previously: openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,881
Original Poster
Rep:
Quote:
Originally Posted by Mechanikx
If by "date structure's variables" you mean its members then no. The members of the date structure are bolded below:
Yeah, that's what I was thinking - after the dot, it's the structure's member variables, that's how I was trying to remember it anyway.
Quote:
"thisDay", "nextDay", "today" and "d" are date structures, so each one contains the three bolded members above.
That's pretty much what I was confused about; so "thisDay", "nextDay", "today" and "d" are actually structures, not just the variables of the "date" structure? Because this is the part that just isn't clear to me.
That's pretty much what I was confused about; so "thisDay", "nextDay", "today" and "d" are actually structures, not just the variables of the "date" structure?...
You got it.
Quote:
Originally Posted by jsbjsb001
...Because this is the part that just isn't clear to me.
Let's simplify things and just create a date structure that will hold today's date. First we create the template. This template will be used in the creation of other structures we want to be of type date.
Quote:
struct date {
int month;
int day;
int year;
};
You can't assign any values to the template because it's a declaration so there's no memory allocated for it. If we want to use a date structure we have to create one:
Quote:
struct date today;
today is now a date structure with the members month, day, year and we are able to assign values to them:
Distribution: Currently: OpenMandriva. Previously: openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,881
Original Poster
Rep:
Yeah, I think so. But just to make sure, and using the current example:
The structure is of "type date", with the three integer members "month", "day" and "year". The "today" structure is of "type date", with the same three integer members, that would look like "today->month", "today->day" and "today->year"?
Also, if I had something like below;
Code:
struct date {
int month;
int day;
int year;
struct time {
int seconds;
int minute;
int hour;
};
};
struct date today;
struct time thisDay;
It would look like "today->month", etc, etc, and for the nested "thisDay" structure of "type time", it would look like "today.thisDay->seconds", etc, etc?
I feel that it might have been best to have started a new thread some time ago.
What you say is not accurate:
Code:
struct date {
int month;
int day;
int year;
struct time {
int seconds;
int minute;
int hour;
};
};
struct date today;
struct time thisDay;
// And your comment/question:
It would look like "today->month", etc, etc, and for the nested "thisDay" structure of "type time", it would look like "today.thisDay->seconds", etc, etc?
None of those structures are pointers.
A better way to write that structure, containing another structure is the following (And note that indentation here helps, and that I've logically reordered the time elements):
Code:
struct date {
int month;
int day;
int year;
struct time {
int hour;
int minute;
int seconds;
};
};
You do not need to declare a struct time.
Code:
struct date today; // declaration of a struct date variable name is today.
// How you access the elements of the structure, all of them.
today.month = 8; // August
today.day = 17; // 17
today.year = 2019; // 2019
today.time.hour = 11; // 11:00
today.time.minute = 26; // 26 minutes after the hour
today.time.seconds = 5; // 5 seconds after the minute
// This makes a structure of type 'date', variable named 'today' containing the data: August 17, 2019 11:26:05
If there were pointers you need to make sure said pointers are pointing to memory bolded there because I've detected this is a rather large problem.
Code:
struct time {
int hour;
int minute;
int seconds;
};
struct date {
int month;
int day;
int year;
struct time *tod;
};
For when you use that, you need to use malloc() or calloc() to declare a struct time OR you need to declare a struct time as a variable and then point to it using the "tod" pointer declared in the struct date.
Code:
struct time now;
struct date today;
today.month = 8;
today.day = 17;
today.year = 2019;
today.tod = &now;
// And now you can use the -> reference, and have to because it is a pointer.
today.tod->hour = 11;
today.tod->minute = 26;
today.tod->seconds = 5;
Recommend you don't play around with providing the values for the structure variables at time of declaration. I notice that you tend to do that, and get into trouble. Just advice there.
A better way to write that structure, containing another structure is the following (And note that indentation here helps, and that I've logically reordered the time elements):
Code:
struct date {
int month;
int day;
int year;
struct time {
int hour;
int minute;
int seconds;
};
};
Not sure this makes sense, I get a warning when compiling it:
Code:
tmp.c:9:5: warning: declaration does not declare anything
};
^
Distribution: Currently: OpenMandriva. Previously: openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,881
Original Poster
Rep:
Quote:
Originally Posted by rtmistler
I feel that it might have been best to have started a new thread some time ago.
...
I figured that structures was relevant, that's why I continued with this thread. But that said, if the mod's feel the posts after post #131 (or whatever other post) should be split off into it's own thread, I don't have any issues with that - so I'll leave it up to the mod's/LQ to decide. Thanks for that post of yours tho RT, it was very helpful.
Anyway, I've been doing a little practice with nested structures, and I think I've got it. I had a look at both the C book and this site, and I've written some code that compiles without any warnings or errors. It just display's today's date (for where I live) and the time when I was writing the same code (I haven't used any pointers in it tho). But I'm still getting use to how to properly indent struct statements/structures tho, so sorry if my indenting is a little off (and kwrite keeps messing up my formatting when I copy and paste any code - written by myself or not).
Code:
#include <stdio.h>
int main(void) {
struct date {
int day;
int month;
int year;
struct time {
int hour;
int minute;
int seconds;
} now;
};
struct date today;
today.day = 18;
today.month = 8;
today.year = 2019;
today.now.hour = 1;
today.now.minute = 51;
today.now.seconds = 32;
printf("Date and time is: %i/%i/%i %i:%i:%i\n", today.day, today.month, today.year, today.now.hour, today.now.minute, today.now.seconds);
return 0;
}
Or perhaps the presence of tabs entirely. I suggest to never use TABS, except in a Makefile where they are required, or any other particular file similar in nature. C source files, I feel should all contain spaces as opposed to tabs.
Just my humble opinion.
And sorry once again for posting code, which was not compiled, just typed off the cuff. Obviously caused a bit of confusion there.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.