How to compare day from the ctime lib with a day string? - c++

does anyone know how to compare the day with day string.. It might sound confusing but I had this thing in mind.. Hope the code clears everything out
#include <iostream>
#include <ctime>
int main()
{
/// current date/time based on current system
time_t now = time(0);
/// convert now to string form
tm *ltm = localtime(&now);
cout << "The local date and time is: " << ltm << endl;
if(*ltm == "Mon") Monday();
else if(*ltm == "Tue") Tuesday();
else if(*ltm == "Wed") Wednesday();
else if(*ltm == "Thu") Thursday();
else if(*ltm == "Fri") Friday();
else if(*ltm == "Sat" || *ltm == "Sun") Monday();
return 0;
}
and that's the one of the huge error message board,I'm giving just that one line because the rest of the errors are the same but for different lines.
/home/shadowdragon/Documents/uktc_schdule/UKTC_schedule/main.cpp|90|error: no match for ‘operator==’ (operand types are ‘tm’ and ‘const char [4]’)|

You don't even need to compare it with a string (viz. const char*)... <ctime> provides its own method to compare all that...
First, make an enumerator that keeps track of all days of the week (0-6),
enum
{
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
};
Now check it like this:
if (*ltm.tm_wday == Sunday)
std::cout << "Its Sunday!" << std::endl;
Do the same for the other days as well...
If you look closely, you can see that the struct member tm_wday returns a number between the range 0-6 (Sunday to Monday) and the enumerator is just to clarify it... (So that you don't get confused with if (*ltm.tm_wday == 0 /*Sunday*/) or something like that...)
See more about the tm structure here...
There is even a C++ alternative here...
Note: std::tm gives you the accurate UTC time, so it is recommended to check it out, and use this function instead of localtime() as pointed out in the comments section...
Edit: If you have to compare it with a string... then maybe a function can be of help...
const char * GetDay(struct tm * tm)
{
switch (tm->tm_wday)
{
case 0:
return "Sun";
case 1:
return "Mon";
case 2:
return "Tue";
case 3:
return "Wed";
case 4:
return "Thu";
case 5:
return "Fri";
case 6:
return "Sat";
default: return "";
}
}
Then do something like:
if (GetDay(ltm) == "Sun")
std::cout << "Its Sunday again!" << std::endl;
Kind regards,
Ruks.

Related

Syntax of a string function definition [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Can someone explain to me what I'm doing wrong with the syntax below? My textbook doesn't have any examples of user-defined string functions and I can't figure out what I should be doing. Thanks in advance!
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <string>
string dayOfWeek(int day);
using namespace std;
int main()
{
cout << "Please enter a day of week (0 for Sunday, 1 for Monday, etc): ";
cin >> day;
cout << "The name of the day of the week is: " dayOfWeek(day) << endl;
}
string dayOfWeek(int day)
{
if (day == 0)
return "SUNDAY";
else if (day == 1)
return "MONDAY";
else if (day == 2)
return "TUESDAY";
else if (day == 3)
return "WEDNESDAY";
else if (day == 4)
return "THURSDAY";
else if (day == 5)
return "FRIDAY";
else if (day == 6)
return "SATURDAY";
}
#include <string>
#include <iostream>
std::string dayOfWeek(int day)
{
if (day == 0)
return "SUNDAY";
else if (day == 1)
return "MONDAY";
else if (day == 2)
return "TUESDAY";
else if (day == 3)
return "WEDNESDAY";
else if (day == 4)
return "THURSDAY";
else if (day == 5)
return "FRIDAY";
else if (day == 6)
return "SATURDAY";
return "Invalid input!"; // May be you should guarantee a return value.
}
int main() {
std::cout << dayOfWeek(5) << std::endl;
}
should work as expected.
The crux of the problem is here:
string dayOfWeek(int day);
using namespace std;
The using is after code that depends on it, so the compiler goes looking for string and can't find it. It doesn't go looking for std::string because it hasn't been told to yet.
You could move using up a few lines, but for the many reasons covered in the answers to Why is "using namespace std" considered bad practice? and a few not covered, you're probably better off not putting
using namespace std;
in your code at all. Prefix the std:: explicitly and you can avoid a litany of nasty surprises.
I also recommend following #πάνταῥεῖ example with where the function was placed. Forward declaring and then declaring gives you two places to have to change code and one more place to have a bug. Declaring the function ahead where it will be used mean you only ever have to change one declaration.
Putting it all together with a few other small tweaks:
#include <string>
#include <iostream>
std::string dayOfWeek(int day)
{
switch (day) // for stuff like this, I like a switch. I find it looks nicer.
{
case 0:
return "SUNDAY";
case 1:
return "MONDAY";
case 2:
return "TUESDAY";
case 3:
return "WEDNESDAY";
case 4:
return "THURSDAY";
case 5:
return "FRIDAY";
case 6:
return "SATURDAY";
default:
return "No such day"; // functions must always return something.
// in this case what will cout print if you
// don't return a string? Don't know?
// Don't feel bad. Neither do I.
// Welcome to Undefined Behaviour
}
}
int main()
{
int day; //this was missing
std::cout << "Please enter a day of week (0 for Sunday, 1 for Monday, etc): ";
std::cin >> day;
std::cout << "The name of the day of the week is: " << dayOfWeek(day) << std::endl;
}
There's one other trick you can use to get rid of the if or switch entirely
#include <string>
#include <iostream>
// define an array of days of the week to print. const means dayOfWeek cannot be changed
const std::string dayOfWeek[] =
{
"SUNDAY",
"MONDAY",
"TUESDAY",
"WEDNESDAY",
"THURSDAY",
"FRIDAY",
"SATURDAY"
};
int main()
{
unsigned int day;
//Note unsigned int. Negative numbers are now disallowed
std::cout << "Please enter a day of week (0 for Sunday, 1 for Monday, etc): ";
// keep looping until user provides a good number
while (!(std::cin >> day) // user MUST input a number
|| day > 6) // number is a usable number
{
std::cin.clear(); // clean up bad input
std::cout << "Please enter a day of week (0 for Sunday, 1 for Monday, etc): ";
}
// since we know day is a usable (0..6) number we can read the day out of the array
std::cout << "The name of the day of the week is: " << dayOfWeek[day] << std::endl;
}

How do I display the output of my C++ class

Hello guys I am trying to create a date class in C++ where it display the default date, displays a short set date, displays a long set date, just display a set year. However, I am trying this display the contents of the class when I input the data but I am getting an error "Use of undeclared identifier 'setDate'
Here is the header file code:
#ifndef dateClass_h
#define dateClass_h
using namespace std;
class DateObj
{
public:
int setDate(int month, int day, int year);
void shortDate(int month, int day, int year);
void longDate(string month, int day, int year);
//return the year
int getYear(int year){
return year;
}
private:
int month;
int day;
int year;
};
#endif /* dateClass_h */
Here is my implementation file code:
#include <stdio.h>
#include <iostream>
#include <string>
#include "dateClass.h"
using namespace std;
//setDate Method
int DateObj::setDate(int month, int day, int year){
//setMonth = month;
//day = setDay;
//year = setYear;
//check to make sure month is between 1 - 12.
if(month < 1 || month > 12){
cout << "This is an invalid Month. Please enter a month that is between 1 and 12: " << endl;
}
//check to make sure day is between 1 -31.
if(day < 1 || day > 31){
cout << "This is an invalid Day. Please enter a day that is between 1 and 31: " << endl;
}
//check to make sure year is greater than zero.
if(year < 0){
cout << "This is an invalid Year. Please enter a year that is greater than Zero" << endl;
}
return setDate(month,day,year);
}
And here is my main program code:
#include <iostream>
#include <string>
#include "dateClass.h"
using namespace std;
int main() {
DateObj myDate;
myDate.setDate(12, 25, 2016); //set the date to Dec 25, 2016.
cout << "The current date is: " << setDate() << endl;
return 0;
}
I will just like to know why I am getting this error and what I will need to fix in my class or main program.
Edit
I got the program to compile butI got the following error "EXC_BAD_ACCESS (code=2, address=0x7fff5f3fffe8) at the return setDate(month, day, year) break point.
#include <iostream>
#include <string>
#include "dateClass.h"
using namespace std;
int main() {
DateObj myDate;
myDate.setDate(12,25,2016); //set the date to Dec 25, 2016.
cout << "The current date is: " << myDate.setDate(12, 25, 2016) << endl;
return 0;
}
There appears to be no implementation for your shortDate function.
You have it in your header file, but you don't appear to have it in your dateClass.cpp file. You need to implement it in your dateClass.cpp file similar to how you did for setDate.
You're getting the error because it can't find any implementation.
The reason you are getting an error is because setDate() is a void function. When you try to use setDate() in the line:
cout << "The current date is: " << setDate() << endl;
you get an error because setDate() needs to return an std::ostream & object or some other data that is convertible. I recommend using setDate(int month, int day, int year) purely to set the data members of your class and create a separate function to actually print out the values.
As an alternative, you could overload setDate() so that it returns an acceptable data type, like so:
#include <iomanip>
//the parameter 'right' is required for chaining together different << when forming output
std::ostream & DateObj::setDate(std::ostream & right) {
//displays the date in mm/dd/yyyy format
//setfill defines a character to fill empty spaces created by setw
right << std::setfill('0') << std::setw(2) << month
<< '/' << std::setfill('0') << std::setw(2) << day
<< '/' << std::setfill('0') << std::setw(4) << year;
return right;
}
Well, for one thing you're calling setDate() inside setDate() in such a way that it will infinitely just call itself. You'll call setDate(), which will call setDate(), which will call setDate() and so on. I'm kind of a noob too, but I'm pretty sure what you're getting is a stack overflow error (Hey, title drop! :D). A stack overflow happens when you allocate too many variables and run out of memory. So because you're calling setDate() infinitely, you are also making infinite versions of the variables in it, and filling up all your memory.
For another, set date doesn't currently actually do anything. It checks to see if you have valid input, then calls itself again. From the name, I assume it's meant to populate your member variables? If that's what it's supposed to do, it should probably look more like this:
int DateObj::setDate(int month, int day, int year){
//check to make sure month is between 1 - 12.
if(month < 1 || month > 12){
cout << "This is an invalid Month. Please enter a month that is between 1 and 12: " << endl;
}
//check to make sure day is between 1 -31.
if(day < 1 || day > 31){
cout << "This is an invalid Day. Please enter a day that is between 1 and 31: " << endl;
}
//check to make sure year is greater than zero.
if(year < 0){
cout << "This is an invalid Year. Please enter a year that is greater than Zero" << endl;
}
//the part that actually sets the variables. Aka, the important bit.
month_ = month;
day_ = day;
year_ = year
}
The trailing underscores on month, day and year are just style things, I like to use them for member data so that I can use those names again as local variables in my functions, which was useful here if you noticed. Once you've put the data into your variables, it should be pretty easy to display everything. Just do something like:
cout << month_ << "/" << day_ << "/" << year_ << endl;
That will output your date to the console in a format something like this: 3/12/2016.

Receiving a string, checking for a Capital Letter

What Im trying to do is check if the user-supplied string has a capital letter or not.
The first part of the code with the enumerated constant, is just there for another method,
which I got to work using numbers assigned to the words Sunday = 7, Monday=1, Tuesday=2, etc. I'm trying have the user not supply numbers, but the actual word (Sunday, Monday, Tuesday), but I want them to specify the day of the week with a capital letter.
Problem I get: compiles fine, but anything you type in is somehow redirected along an execution path that always returns "Retype w/ a capital letter." This happens if I type in fjdkalfda or sunday or Sunday or whatever. Here is the code. Sorry if its not in code format, first time user of Stack Overflow.
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
int main(){
/*enum DaysOfWeek {
Monday = 1,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
};*/ //I'm not using this, but I can get my code to work with this
//enumerated constant by asking the user to input a number corresponding
//to the day of the week and then using if-else statements to check, say,
// int Day;
// cin >> Day
// then use if statements to check if Day = a certain number, to give output
cout << "Enter the day of week with a capital letter: ";
string Day;
getline(cin, Day);
if (Day == ("monday") || ("tuesday"))
cout << "Retype w/ a capital letter" << endl;
else if (Day == ("wednesday") || ("thursday"))
cout << "Retype w/ a capital letter" << endl;
else if (Day == ("friday") || ("saturday"))
cout << "Retype w/ a capital letter" << endl;
else if (Day == ("sunday"))
cout << "Retype w/ a capital letter" << endl;
else
{
if (Day == "Monday")
cout << "Moon" << endl;
else if (Day == "Tuesday")
cout << "Mars" << endl; //continue with the days etc...
}
return 0;
}
One would observe that there is a function called toupper which can turn a lower case letter into upper case, and leave an upper case letter alone. Perhaps you can reuse this function to help solve your problem with less code.
I am inferring from your code that you are only interested in verifying that the first letter is a capital letter. Is that correct?
There is an isupper function in ctype.h that returns true if a char is upper case:
#include <ctype.h>
...
isCapitalized = isupper(str[0]);
...
I'm assuming you're actually not bothered about capitol letters if we can somehow organize the input choice in an enum type. Instead of this enum classes would be a better choice if you have C++11. If not, it would be quite easy to change this code for normal enums
If you're using gcc/g++, you may need to include prefix -std=c++11
Note: you may want to add another enum element to enum class Days such as null_day. Or even better, Make sure user inputs the correct day, until he/she does, don't carry on with program (hint: use while loop when using getline)
#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
using std::string;
using std::transform;
using std::cout;
using std::cin;
using std::endl;
// only in C++ 11
enum class Day {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday};
int main () {
cout << "Enter the day of week: ";
// store day from user input, transform all to lower case so
// we don't bother with user input type (only error in spelling will be the problem now)
string get_day;
getline(cin, get_day);
transform(get_day.begin(), get_day.end(), get_day.begin(), tolower);
// define instance of enum class Day, and sort out what day user has input
// note that if you do not initialize myDay object, it will set to the first
// element in the enum class Day above (which is Monday). This will happen
// if user input is not allowed to initialize it. See the << >> section below
Day myDay;
if (get_day == "monday")
myDay = Day::Monday;
else if (get_day == "tuesday")
myDay = Day::Tuesday;
else if (get_day == "wednesday")
myDay = Day::Wednesday;
else if (get_day == "thursday")
myDay = Day::Thursday;
else if (get_day == "friday")
myDay = Day::Friday;
else if (get_day == "saturday")
myDay = Day::Saturday;
else if (get_day == "sunday")
myDay = Day::Sunday;
else
<< ERROR CODE HERE >>
<< MAYBE A WHILE LOOP UNTIL USER INPUTS CORRECT DATA >>
// perform your calculations/operations/etc separate from above
if (myDay == Day::Monday)
cout << "Moon" << endl;
else if (myDay == Day::Tuesday)
cout << "Mars" << endl; //continue with the days etc...
return 0;
}

comparing strings c++ with wildcard values

I've been lurking around here for a long time, thank you for all your help in the past, even if this is the first question I've had to ask.
I'm trying to make a simple database program, and I am stuck the search requirement for it.
When searching, the user needs to be able to enter a question mark if they don't know a value. If you knew a movie was from the 90's you could enter 199? and it would find all the movies that matched 199_. I keep getting errors when I compile, "cannot convert 'char*' to 'char ()[5] for argument '2' to 'bool compareYears(const char, char (*)[5]"
I am trying to figure most of it out on my own, and I like to separate the functions and make them work in a separate .cpp file before adding them to the main file, just to make debugging easier.
#include <iostream>
#include <cstring>
#include <fstream>
#include <cctype>
using namespace std;
const int yearLength = 4;
typedef char year[yearLength + 1];
bool compareYears(const year year1, year year2[]);
int main()
{
year year1 = "1992"; //year from database, will be assigned the
// variable when implemented in main program.
year year2; //year entered by user, it will be compared to year1.
cout << "Enter a year to search for: ";
cin >> year2;
cout << endl;
if((compareYears(year1, year2)) == true)
cout << "they match\n";
if((compareYears(year1, year2)) == true)
cout << "they do not match\n";
return 0;
}
bool compareYears(const year year1, year year2[])
{
for(int i = 0; i < 4; i++)
{
if (strncom(year1, year2[i], 4) ==0)
return true;
else if (strncmp(year1, "????", 4) == 0)
return true;
else
return false;
}
}
Thanks for helping me out with this, usually the most help I get from others is useless or insulting. What I need help with most is getting rid of that compiler error. I cannot figure it out for the life of me.
First of all read this: typedef fixed length array
Then, use this typedef:
typedef struct year { char characters[4]; } year;
and change the code this way:
int main()
{
year year1;
year1.characters= "1992"; //year from database, will be assigned the variable when implemented in main program.
year year2; //year entered by user, it will be compared to year1.
cout << "Enter a year to search for: ";
cin >> year2.characters;
cout << endl;
if((compareYears(year1, year2)) == true)
cout << "they match\n";
else
cout << "they do not match\n";
return 0;
}
bool compareYears(year year1, year year2)
{
if (strncom(year1.characters, year2.characters, 4) ==0)
return true;
else if (strncmp(year1, "????", 4) == 0)
return true;
return false;
}
I also fixed some logical bugs
Just change these lines and it will work...the function declaration needs an array of year and you are trying to pass a variable..
if((compareYears(year1, &year2)) == true) //this changed from year2 to &year2
cout << "they match\n";
if((compareYears(year1, &year2)) == true) //this changed from year2 to &year2
cout << "they do not match\n";
The type of the year2 argument for compareYears looks strange. It looks like this argument is the mask to test against, i.e. a literal year like 1992 or something using wildcards. Hence, how about making it a char array of yearLength bytes?
It might be even easier to write just a generic function which is given two strings or arbitrary length (the second of which may use wildcards) and sees whether they are equal. The quality test could first see whether both strings are the same length and if so, whether the character at every position in both strings is either equal or the character at the given position in the second string is a '?'. You could use a single loop to walk over both strings in parallel to do this.

C++ warning C4800 - 'int' forcing value to bool 'true' or 'false' with switch statement

In this segment of code, toPurchase is converted from an integer to a bool when it is initialised with player->giveOptions() (which returns an integer, not a boolean) very near the end of this code. After, there is a switch(toPurchase), which then the compiler says won't work because toPurchase has been converted to a bool. Why?
int loc = player->giveOptions(4,"Trainers","Market","Inn","Back","");
int chos;
bool success = true;
bool toPurchase = false;
switch(loc){
case 1:
text.push_back("Hello, "+player->name+".");
if (player->firstTrainerVisit){
text.push_back("I'm not sure if anyone's told you, but there's been some strange talk about you lately...");
text.push_back("Hmm... A lot of people are scared of you.");
text.push_back("Anyway, nice to meet you. I'm Yobbee, the village trainer.");
text.push_back("You'll need training up before meeting the village elders.");
text.push_back("Usually, you need to pay to get trained by me, but as a first time bonus I'll teach you for free.");
text.push_back("After you've been trained, you get a skill point, which you can use to increase one of your abilities.");
}
text.push_back("Would you like to be trained today?");
NPCTalk("Yobbee (Trainer)",text);
text.clear();
chos = player->giveOptions(2,"Yes","No","","","");
switch(chos){
case 1:
if(!player->firstTrainerVisit){
cout << "This will cost 10 gold. Continue?" << endl;
int purchase = player->giveOptions(2,"Yes","No","","","");
if(purchase)
success = player->spendGold(5);
else
success = false;
}
if (success){
player->awardStat(1,"sp");
cout << "After a day of vigorous training, you find your skills honed." << endl;
}else{
cout << "You don't have enough gold!" << endl;
}
if(player->firstTrainerVisit&&success){
text.push_back("You can use your skill point to increase one of your stats by typing 'sp' any time you are given a choice.");
text.push_back("There are other commands you can use at any choice opportunity as well - just type 'help' to see this one and others.");
NPCTalk("Yobbee (Trainer)",text);
text.clear();
player->firstTrainerVisit = false;
}
break;
case 2:
break;
}
cout << "\nBack to the entrance to Poglathon..." << endl;
system("PAUSE");
Poglathon(text,player);
break;
case 2:
if(player->firstMarketVisit){
text.push_back("Oh... Hello, "+player->name+".");
text.push_back("Ignore other people's looks. You'll find out about all this when you meet the Elders.");
if(!player->firstElderVisit) text.push_back("Oh, you have already? Then I don't feel guilty about not explaining.");
text.push_back("Here, at the market, you can buy new equipment for your travels, such as food, weapons and armour.");
text.push_back("You don't have any gold at the moment, but as a standard first-time visit we will issue you with some leather armour and a rusty dagger.");
text.push_back("Not the best of items, but it'll certainly help!");
text.push_back("The weapon and armour are now in your backpack. To equip items in your backpack, when you are given an option type 'backpack'.");
player->addToBackpackIfSpace("Rusty dagger");
player->addToBackpackIfSpace("Leather armour");
NPCTalk("Market Manager",text);
text.clear();
player->firstMarketVisit = false;
}
cout << "Do you want to purchase anything at the market?" << endl;
toPurchase = player->giveOptions(2,"Yes","No","","","");
switch(toPurchase){
case 1:
cout << "You can't purchase anything yet. NOOB" << endl;
break;
case 2:
break;
}
cout << "\nBack to the entrance to Poglathon..." << endl;
system("PAUSE");
Poglathon(text,player);
break;
}
you switch on toPurchase, which is in fact boolean (declared as boolean in line 4)
Simply change this code:
switch(toPurchase){
case 1:
cout << "You can't purchase anything yet. NOOB" << endl;
break;
case 2:
break;
}
to:
if (toPurchase)
{
cout << "You can't purchase anything yet. NOOB" << endl;
}
C++ is a statically typed language. You have declared toPurchase as a bool variable, so it will remain bool until you violently cast is to something else. But manual casting is not recommended.
Although, int can be casted implicitly to bool, and this happens at
toPurchase = player->giveOptions(2,"Yes","No","","","");
.
This value assignent doesn't change the type of toPurchase like it would do in php for example. It casts the return value of giveOptions to bool, and assigns that casted bool value to to Purchase.