Syntax of a string function definition [closed] - c++

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;
}

Related

The program is giving wrong output for leap year the value at the load variable is wrong i think Ex.1900,1700

*The program is giving wrong output for century year which are not leap Ex.1900,1700.The program is giving wrong output for leap year the value at the load variable is wrong i think Ex.1900,1700. *
#include <iostream>
using namespace std;
int main()
{
int year;
bool t1=true;
cout<<t1;
bool t2=false;
cin>>year;
if(year%4==0)
{
int value=year%100?year%400?t1:t2:t1;
cout<<value;
if(value==t1)
{
cout<<"leap year";
}
else
{
cout<<"not a leap year";
}
}
else
{
cout<<"not a leap year";
}
}
year%100 becomes false when year is divisible by 100 (the remainder is zero) and becomes true when year is not divisible by 100 (the remainder is not zero).
year%400 becomes false when year is divisible by 400 (the remainder is zero) and becomes true when year is not divisible by 400 (the remainder is not zero).
Therefore, you have to judge the number as not leap year when year%100 is false and year%400 is true, and as not leap year otherwise.
In conclusion, the line
int value=year%100?year%400?t1:t2:t1;
should be
bool value=year%100?t1:year%400?t2:t1;
Also I don't think using int here to assign bool variables is reasonable.
In addition to the fix in MikeCAT's answer you can also significantly simplify your code to just a few lines:
#include <iostream>
int main()
{
int year;
std::cin>>year;
bool leap = (year % 4 == 0) && ( (year % 100 != 0) || (year % 400 == 0) );
if(leap)
{
std::cout<<"leap year";
}
else
{
std::cout<<"not a leap year";
}
}
You can use 0 being equivalent to false to make it shorter but I think the first version is more readable:
bool leap = !(year % 4) && ( (year % 100) || !(year%400) );
Once C++20 has been properly implemented by compilers (which is not yet in release) you don't have to reinvent the wheel and can use std::chrono::year::is_leap
#include <iostream>
#include <chrono>
int main() {
using namespace std::chrono;
year y = 1900y;
std::cout << "year: " << static_cast<int>(y)
<< " is " << (y.is_leap()?"":"not ") << "a leap year\n";
}
godbolt

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

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.

C++ Trouble with overloading >>

I'm working on a program and have debugged a lot of what I was doing wrong in it out. I have only one error and have read on stack and other forums about similar problems. But have tried to re-do it over and over with no positive results.
Error Shown in header code and it is:
binary'>>' no operator found which takes a right-hand operand of the type'overloaded-function'(or there is no acceptable conversion)
Month.h
#ifndef MONTH_H
#define MONTH_H
#include <iostream>
#include <string>
using namespace std;
class Month{
private:
static string name;
static int monthNumber;
public:
//Default Constructor
Month(){
setName("January");
setNumber(1);
}
//Input of month only constructor and assigning month number from input of name
Month(string n){
name = n;
setName(n);
if(name == "January" || name == "january"){
setNumber(1);
}
else if(name == "February" || name == "february"){
setNumber(2);
}
else if(name == "March" || name == "march"){
setNumber(3);
}
else if(name == "April" || name == "april"){
setNumber(4);
}
else if(name == "May" || name == "may"){
setNumber(5);
}
else if(name == "June" || name == "june"){
setNumber(6);
}
else if(name == "July" || name == "july"){
setNumber(7);
}
else if(name == "August" || name == "august"){
setNumber(8);
}
else if(name == "September" || name == "september"){
setNumber(9);
}
else if(name == "October" || name == "october"){
setNumber(10);
}
else if(name == "November" || name == "november"){
setNumber(11);
}
else if(name == "December" || name == "december"){
setNumber(12);
}
}
//Input of month number only and assigning month name to that number
Month(int n){
setNumber(n);
}
Month(int n, string m){
monthNumber = n;
name = m;
}
//Set the name of the month
void setName(string n){
name = n;
}
//Set the monthes number (and name for increment and decrement)
void setNumber(int n){
monthNumber = n;
switch(monthNumber){
case 1:
setName("January");
break;
case 2:
setName("February");
break;
case 3:
setName("March");
break;
case 4:
setName("April");
break;
case 5:
setName("May");
break;
case 6:
setName("June");
break;
case 7:
setName("July");
break;
case 8:
setName("August");
break;
case 9:
setName("September");
break;
case 10:
setName("October");
break;
case 11:
setName("November");
break;
case 12:
setName("December");
break;
}
}
//Return the name of the month
string getName(){
return name;
}
//Return the month number
int getNumber(){
return monthNumber;
}
//Overload the -- Operator
Month Month::operator--(int){
if(monthNumber == 1)
{
setNumber(12);
setName("December");
}
else {
monthNumber++;
setNumber(monthNumber);
}
}
Month Month::operator--(){
if(monthNumber == 1)
{
setNumber(12);
setName("December");
}
else {
monthNumber++;
setNumber(monthNumber);
}
}
//Overload the ++ operator
Month Month::operator++(int){
if(monthNumber == 12)
{
setNumber(1);
setName("January");
}
else {
monthNumber++;
setNumber(monthNumber);
}
}
Month Month::operator++(){
if(monthNumber == 12)
{
setNumber(1);
setName("January");
}
else {
monthNumber++;
setNumber(monthNumber);
}
}
//Overloading << and >>
friend ostream &operator<<(ostream &strm, const Month &obj){
strm << "# of Month : " << obj.name << " This Corresponds to the month : " << obj.monthNumber << endl;
return strm;
}
//Error here
//-------------------------------------------------------------------
//binary'>>' no operator found which takes a right-hand operand of
//the type'overloaded-function'(or there is no acceptable conversion)
//-------------------------------------------------------------------
friend istream &operator>>(istream &strm, Month &obj) {
strm >> obj.setNumber >> obj.setName;
return strm;
}
};
#endif
source.cpp
#include "Month.h"
#include <cstdlib>
#include <iostream>
using namespace std;
int main(){
Month coolio, first(1), second("June");
coolio++;
second--;
++first;
cout << "Enter the month number: " << endl;
cin >> coolio;
cout << coolio;
cout << second;
cout << first;
return 0;
}
You cannot read data from an input stream, and combine that with a method call. You need to read the data into a temporary int and a temporary string, and then use these int and string to call the setters, like this:
friend istream &operator>>(istream &strm, Month &obj) {
int number;
string name;
strm >> number >> name;
obj.setNumber(number);
obj.setName(name);
return strm;
}
Moreover, since >> is declared a friend, you can read directly into obj's member variables.
Here are some suggestions on how to simplify your program (so the rest of us don't have to wade through hundreds of lines of code):
Assign To Members directly
You don't need to call setName within the setNumber method.
Access the name variable directly.
One Text Case, One compare
Your code will fail for the case jUNe.
You could convert your month name to all lower case or all upper case before you compare. This reduces your if-else ladder by half.
Search the web for "c++ transform toupper".
Remove Month Compares
There's a fancy technique for mapping month names to numbers, but we'll not use that. You can use an array instead. Let the array index represent the month number:
static const char month_number_to_name[13] =
{
"Nothing",
"january", "february", "march", "april", "may", "june",
"july", "august", "september", "october", "november", "december",
};
// ...
std::cout << "The name of month 10 is: "
<< month_number_to_name[10]
<< "\n";
Save Month Name or Number
There is no need to save both the month name and number. With the translation array above you can convert between name and number.
I recommend keeping the month number variable. If you need the name, using the month number to get the name, the process the name.
Small size, small quantity of defects
There is much research in the programming industry that states the longer a program is, the high probability it will have more defects than a shorter one. Just consider the typing alone. More letters typed increases the chance for a typo.
Use data structures to your advantage to reduce your program size.

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.