473,395 Members | 1,574 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Stroustrup 5.9 exercise 13 (creating a structure)

problem: define a /struct Date/ to keep track of dates. provide
functions that read Dates from input, write Dates to output &
initialize a date with date.

solution: i thought of a /vector/ of /Date structures/. "Date" struct
carries 3 things: month, date & year. i wrote the following code & of
course it gives an error:
#include <iostream>
#include <string>
#include <vector>

struct Date {
std::string month;
int date;
int year;
};

std::vector<Datevd;

void create_date(std::string m, int d, int y) {
Date da = {m, d, y};
vd.push_back(da);
}

void date_input(std::vector<Datevdate) {
std::string month;
int date, year;

std::cout << "Enter Date (MM DAY YEAR): ";
std::cin >month;
std::cin >date;
std::cin >year;

create_date(month, date, year);
}

void print_date(Date* vdate) {
std::cout << vdate->month << '\n'
<< vdate->date << '\n'
<< vdate->year << '\n';
}

void print_all_dates(std::vector<Datevdate) {
for(std::vector<Date>::iterator iter=vdate.begin();
iter != vdate.end();
++iter)
{
print_date(*iter);
}
}
int main() {
date_input(vd);
}
--------- error -----------------------------------

05_ex-13.cpp: In function 'void print_all_dates(std::vector<Date,
std::allocator<Date)':
05_ex-13.cpp:44: error: cannot convert 'Date' to 'Date*' for
argument '1' to 'void print_date(Date*)'

----------------------------------------------------

how can i run the desired programme?

Nov 9 '06 #1
9 2242
arnuld wrote:
problem: define a /struct Date/ to keep track of dates. provide
functions that read Dates from input, write Dates to output &
initialize a date with date.

solution: i thought of a /vector/ of /Date structures/. "Date" struct
carries 3 things: month, date & year. i wrote the following code & of
course it gives an error:
#include <iostream>
#include <string>
#include <vector>

struct Date {
std::string month;
int date;
int year;
};

std::vector<Datevd;

void create_date(std::string m, int d, int y) {
Date da = {m, d, y};
vd.push_back(da);
}

void date_input(std::vector<Datevdate) {
what is vdate for?
std::string month;
int date, year;

std::cout << "Enter Date (MM DAY YEAR): ";
std::cin >month;
std::cin >date;
std::cin >year;

create_date(month, date, year);
}

void print_date(Date* vdate) {
std::cout << vdate->month << '\n'
<< vdate->date << '\n'
<< vdate->year << '\n';
}

void print_all_dates(std::vector<Datevdate) {
You probably want

const std::vector<Date>& vdates

to avoid copying.
for(std::vector<Date>::iterator iter=vdate.begin();
iter != vdate.end();
++iter)
{
print_date(*iter);
You should have

print_date(&*iter);

to compile. iter is an iterator, first use operator * to obtain the
object it points to, then use operator & obtain a pointer to that
object, which print_date() requires.
}
}
int main() {
date_input(vd);
}
--------- error -----------------------------------

05_ex-13.cpp: In function 'void print_all_dates(std::vector<Date,
std::allocator<Date)':
05_ex-13.cpp:44: error: cannot convert 'Date' to 'Date*' for
argument '1' to 'void print_date(Date*)'

----------------------------------------------------
Learn to read error messages. It'll but a lot of help!
how can i run the desired programme?
Ben
Nov 9 '06 #2
VJ
arnuld wrote:
problem: define a /struct Date/ to keep track of dates. provide
functions that read Dates from input, write Dates to output &
initialize a date with date.

solution: i thought of a /vector/ of /Date structures/. "Date" struct
carries 3 things: month, date & year. i wrote the following code & of
course it gives an error:
#include <iostream>
#include <string>
#include <vector>

struct Date {
std::string month;
int date;
int year;
};

std::vector<Datevd;

void create_date(std::string m, int d, int y) {
Date da = {m, d, y};
vd.push_back(da);
}

void date_input(std::vector<Datevdate) {
std::string month;
int date, year;

std::cout << "Enter Date (MM DAY YEAR): ";
std::cin >month;
std::cin >date;
std::cin >year;

create_date(month, date, year);
}

void print_date(Date* vdate) {
std::cout << vdate->month << '\n'
<< vdate->date << '\n'
<< vdate->year << '\n';
}

void print_all_dates(std::vector<Datevdate) {
for(std::vector<Date>::iterator iter=vdate.begin();
iter != vdate.end();
++iter)
{
print_date(*iter); <------------------------------------
}
}
int main() {
date_input(vd);
}
--------- error -----------------------------------

05_ex-13.cpp: In function 'void print_all_dates(std::vector<Date,
std::allocator<Date)':
05_ex-13.cpp:44: error: cannot convert 'Date' to 'Date*' for
argument '1' to 'void print_date(Date*)'

----------------------------------------------------

how can i run the desired programme?
marked line should be:
print_date( iter );
otherwise you would pass an object, instead of a pointer to the object
Nov 9 '06 #3

arnuld wrote:
problem: define a /struct Date/ to keep track of dates. provide
functions that read Dates from input, write Dates to output &
initialize a date with date.

solution: i thought of a /vector/ of /Date structures/. "Date" struct
carries 3 things: month, date & year. i wrote the following code & of
course it gives an error:
#include <iostream>
#include <string>
#include <vector>

struct Date {
std::string month;
int date;
int year;
};

std::vector<Datevd;

void create_date(std::string m, int d, int y) {
Date da = {m, d, y};
vd.push_back(da);
}

void date_input(std::vector<Datevdate) {
std::string month;
int date, year;

std::cout << "Enter Date (MM DAY YEAR): ";
std::cin >month;
std::cin >date;
std::cin >year;

create_date(month, date, year);
}

void print_date(Date* vdate) {
std::cout << vdate->month << '\n'
<< vdate->date << '\n'
<< vdate->year << '\n';
}

void print_all_dates(std::vector<Datevdate) {
for(std::vector<Date>::iterator iter=vdate.begin();
iter != vdate.end();
++iter)
{
print_date(*iter);
}
}
int main() {
date_input(vd);
}
--------- error -----------------------------------

05_ex-13.cpp: In function 'void print_all_dates(std::vector<Date,
std::allocator<Date)':
05_ex-13.cpp:44: error: cannot convert 'Date' to 'Date*' for
argument '1' to 'void print_date(Date*)'

----------------------------------------------------

how can i run the desired programme?
in calling function print_date u r using *iter which will give u Date
not Date* (Vector is of Date not Date *) so u can always use

Date date = *iter;
print_date(&date);
or
print_date(&(*iter));
-K2G

Nov 9 '06 #4

arnuld wrote:
problem: define a /struct Date/ to keep track of dates. provide
functions that read Dates from input, write Dates to output &
initialize a date with date.

solution: i thought of a /vector/ of /Date structures/. "Date" struct
carries 3 things: month, date & year. i wrote the following code & of
course it gives an error:
#include <iostream>
#include <string>
#include <vector>

struct Date {
std::string month;
int date;
int year;
};

std::vector<Datevd;

void create_date(std::string m, int d, int y) {
Date da = {m, d, y};
vd.push_back(da);
}
Any law against giving your struct a trivial constructor?

struct Date
{
std::string month;
int date;
int year;

Date() : month( "Jan"), date( 1 ), year ( 2000 ) {}

Date( const std::string & m, int d, int y )
: month ( m ), date( d ), year( y )
{
}
};

then:

vd.push_back( Date( m, d y ) );
void print_date(Date* vdate) {
std::cout << vdate->month << '\n'
<< vdate->date << '\n'
<< vdate->year << '\n';
}
Bad use of pointers for more than one reason. The user is never going
to pass in a NULL one (if they do it's UB). In addition your print
function isn't going to modify the date so use a const reference. There
is another big reason why you'll want your function to take a const
reference as you'll see below. Anyway

void print_date( const Date & vdate )
{
std::cout << vdate.month << '\n' << vdate.date << '\n' << vdate.year
<< '\n';
}

Of course we can do better than specify cout as the output source. The
best is simply to overload operator << for dates so

std::ostream & operator<<( std::ostream & os, const Date & vdate )
{
os << vdate.month << '\n' << vdate.date << '\n' << vdate.year <<
'\n';
return os;
}

void print_date( const Date & vdate )
{
std::cout << vdate;
}
void print_all_dates(std::vector<Datevdate) {
for(std::vector<Date>::iterator iter=vdate.begin();
iter != vdate.end();
++iter)
{
print_date(*iter);
}
}
Once again you need to pass by const reference. Although vectors are
copyable it is best not to copy it but to pass it by const reference.

In addition, having now rewritten the print_date function to take a
const reference we can make use of the std::for_each algorithm. Thus:

void print_all_dates( const std::vector< Date & vdates )
{
std::for_each( vdates.begin(), vdates.end(), print_date );
}

If you want to use operator<< then it's a bit more complex but
something you should get used to:

void print_all_dates( const std::vector< Date & vdates )
{
std::copy
(
vdates.begin(), vdates.end(),
std::ostream_iterator< Date >( cout, "" ) // "" is a
delimiter
);
}

Of course you won't really need to write these functions at all because
their implementations are just one-liners so you use the one-liners
when you need to print them all anyway.

You will need to include headers <iteratorand <algorithm>

Nov 9 '06 #5
benben wrote:
what is vdate for?
oops! i have removed it.
You probably want

const std::vector<Date>& vdates

to avoid copying.
yes, exactly, changed that too.
You should have

print_date(&*iter);

to compile. iter is an iterator, first use operator * to obtain the
object it points to, then use operator & obtain a pointer to that
object, which print_date() requires.
i changed it and it works but why /&/ works and /*/ gives an error. i
mean, you asked me to use "reference" to obtain a "pointer" and it
works but if i use "pointer" to obtain a "pointer" (i.e. **iter) i get
an error. why?
Learn to read error messages. It'll but a lot of help!
i think this will take experience which takes a lot of time & i am
investing my time into C++ :-)

Nov 9 '06 #6
Earl Purple wrote:
Any law against giving your struct a trivial constructor?
i am a newbie to C++ so i dont know what are constructors.

Bad use of pointers for more than one reason. The user is never going
to pass in a NULL one (if they do it's UB).
what does this mean?
In addition your print
function isn't going to modify the date so use a const reference. There
is another big reason why you'll want your function to take a const
reference as you'll see below. Anyway
that is a good reason & was my intention. i tried it before but it
raises an error.
Of course we can do better than specify cout as the output source. The
best is simply to overload operator << for dates so

std::ostream & operator<<( std::ostream & os, const Date & vdate )
{
os << vdate.month << '\n' << vdate.date << '\n' << vdate.year <<
'\n';
return os;
}
out of my head.

Once again you need to pass by const reference. Although vectors are
copyable it is best not to copy it but to pass it by const reference.
yes, Stroustrup does this most of the time. someone at my previous
other thread pointed this thing to me with C++ FAQs on "const
correctness". i understand it.
In addition, having now rewritten the print_date function to take a
const reference we can make use of the std::for_each algorithm. Thus:

void print_all_dates( const std::vector< Date & vdates )
{
std::for_each( vdates.begin(), vdates.end(), print_date );
}
good. i will do this.
If you want to use operator<< then it's a bit more complex but
something you should get used to:

void print_all_dates( const std::vector< Date & vdates )
{
std::copy
(
vdates.begin(), vdates.end(),
std::ostream_iterator< Date >( cout, "" ) // "" is a
delimiter
);
}
out of my head.
Of course you won't really need to write these functions at all because
their implementations are just one-liners so you use the one-liners
when you need to print them all anyway.

You will need to include headers <iteratorand <algorithm>
that is fine & i will use them in future when i will be able to
understand them & that will happen when Stroustrup will explain.

thanks a lot.

Nov 9 '06 #7

arnuld wrote:
Earl Purple wrote:
Any law against giving your struct a trivial constructor?

i am a newbie to C++ so i dont know what are constructors.
I know that Stroustrup doesn't believe in teaching C first so I don't
get why he hasn't yet taught using constructors.

Anyway, in its simplest form, a constructor is a simple function. Now
maybe he has taught you that in C++ structs and classes are the same
and that they can have member functions that access their member
variables. The constructor is the first function that is called when
you create an instance of a struct or class - it is only called at this
time and cannot be subsequently called later. It has the form that I
have shown you and in its simplest form is used to initialise the class
members.
Bad use of pointers for more than one reason. The user is never going
to pass in a NULL one (if they do it's UB).

what does this mean?
It means "undefined behaviour", which is what happens in C++ when you
do something illegal. It will often cause your program to crash but is
not guaranteed to do so, and it may work at first then crash or err
later on.
In addition your print
function isn't going to modify the date so use a const reference. There
is another big reason why you'll want your function to take a const
reference as you'll see below. Anyway

that is a good reason & was my intention. i tried it before but it raises an error.
Probably because you did it wrong. Did you use -syntax? With a
reference you use . syntax.
Of course we can do better than specify cout as the output source. The
best is simply to overload operator << for dates so

std::ostream & operator<<( std::ostream & os, const Date & vdate )
{
os << vdate.month << '\n' << vdate.date << '\n' << vdate.year <<
'\n';
return os;
}

out of my head.
ostream is a generic stream. The above writes the data of your class in
text format into any stream but it doesn't specify what type of stream
it is. It could be to the console, it might be to a file or it might be
to memory.
void print_all_dates( const std::vector< Date & vdates )
{
std::for_each( vdates.begin(), vdates.end(), print_date );
}

good. i will do this.
This is the simplest form of an algorithm .It is clear this is not
above your head so perhaps you can start to think along these lines.

When you want print_date to take extra parameters then you can learn to
write a simple functor.
If you want to use operator<< then it's a bit more complex but
something you should get used to:

void print_all_dates( const std::vector< Date & vdates )
{
std::copy
(
vdates.begin(), vdates.end(),
std::ostream_iterator< Date >( cout, "" ) // "" is a
delimiter
);
}

out of my head.
Yes, probably would be if std::ostream is, as we've taken this to a
higher level of complexity.
std::copy is a generic algorithm that takes a sequence and writes it to
another location. You've come across iterators: they use operator* and
operator ++ just like pointers do, except that they are more generic
than a pointer, i.e. a pointer is a special type of iterator.
Algorithms make use of the fact that iterators use operator++ and
operator*. operator* normally returns a reference to something. Now
references can be const (read-only) or non-const. copy requires a
non-const reference because it is going to write to it using
assignment (operator=).

However it doesn't have to be a reference at all. It can be an instance
of a class that wraps a reference. It can even be the iterator itself.
In fact ostream_iterator is a cheat with regards to operator++ as it
doesn't change anything at all - it always writes to the end of the
stream. It is also a cheat with regards to operator* which also returns
itself. All the work is done in operator= which simply writes the
object to the stream.

Note that back_inserter is another example of an iterator that
"cheats".
that is fine & i will use them in future when i will be able to
understand them & that will happen when Stroustrup will explain.
I'm sure he will. If not, then read Scott Meyers' "Effective STL". It
was that book that converted me to using them.

Nov 9 '06 #8
arnuld <ar*****@gmail.comwrote:
benben wrote:
>You should have

print_date(&*iter);

to compile. iter is an iterator, first use operator * to obtain the
object it points to, then use operator & obtain a pointer to that
object, which print_date() requires.

i changed it and it works but why /&/ works and /*/ gives an error. i
mean, you asked me to use "reference" to obtain a "pointer" and it
works but if i use "pointer" to obtain a "pointer" (i.e. **iter) i get
an error. why?
The meaning of '&' and '*' changes depending on the context.

For example:
int* p = new int(42); // * means that p is a pointer to int
int i = *p; // * means to dereference the pointer p
int j = i * i; // * means to multiply i by i

int& r = i; // & means that r is a reference to i;
int* p2 = &i; // & means to take the address of i
int a = i & i; // & means to do bitwise-and operation

--
Marcus Kwok
Replace 'invalid' with 'net' to reply
Nov 9 '06 #9

arnuld wrote in message ...
>
i changed it and it works but why /&/ works and /*/ gives an error. i
mean, you asked me to use "reference" to obtain a "pointer" and it
works but if i use "pointer" to obtain a "pointer" (i.e. **iter) i get
an error. why?
Another way to write **iter is *iter[]. So, then you would be trying to pass
an array of pointers (loosely speaking).

(&) take the address of (*iter) the object the iter is pointing to.

--
Bob R
POVrookie
Nov 9 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

26
by: Oplec | last post by:
Hi, I am learning standard C++ as a hobby. The C++ Programming Language : Special Edition has been the principal source for my information. I read the entirety of the book and concluded that I...
7
by: arnuld | last post by:
problem: define functions F(char), g(char&) & h(const char&). call them with arguments 'a', 49, 3300, c, uc & sc where c is a char, uc is unsigned char & sc is signed char. whihc calls are legal?...
0
by: arnuld | last post by:
Stroustrup has a table in section 4.9 of declarations and definitions. he asks to write a similar table but in opposite sense: char ch; // declaration with definition he asks to do the...
0
by: arnuld | last post by:
this programme runs without any trouble. it took 45 minutes of typing. i posted it here so that people can save their precious time: // Stroustrup special edition // chapter 4 exercise 2 //...
16
by: arnuld | last post by:
i did what i could do at Best to solve this exercise and this i what i have come up with: ----------- PROGRAMME -------------- /* Stroustrup 5.9, exercise 3 STATEMENT: Use typedef to define...
11
by: arnuld | last post by:
/* Stroustrup: 5.9 exercise 7 STATEMENTS: Define a table of the name sof months o fyear and the number of days in each month. write out that table. Do this twice: 1.) using ar array of char...
6
by: arnuld | last post by:
this one was much easier and works fine. as usual, i put code here for any further comments/views/advice: --------- PROGRAMME ------------ /* Stroustrup: 5.9 exercise 7 STATEMENTS: Define a...
14
by: arnuld | last post by:
there is no "compile-time error". after i enter input and hit ENTER i get a run-time error. here is the code: ---------- PROGRAMME -------------- /* Stroustrup, 5.9, exercise 11 STATEMENT:...
27
by: arnuld | last post by:
it works fine without any trouble. i want to have advice on improving the code from any angle like readability, maintenance etc: ---------- PROGRAMME ------------ /* Stroustrup, 5.9, exercise 11...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.