Help with Char* (i.e. c = atoi(year+2))

T

Thomas J. Gritzan

yogi_bear_79 said:
int main ()
{
char longDate[20];

cout << " \n Enter a date in the following format(February 27,
2008):";
cin.getline(longDate,20);
cout << day_of_the_week(longDate);
}

int day_of_the_week(char longDate[])
{
char* nextToken;
int a, b, c, d, r, w, x, y, z;

char *month = strtok_s(longDate, " ", &nextToken);
char *day = strtok_s(NULL, " ", &nextToken);
char *year = strtok_s(NULL, "\0", &nextToken);
......


This is the code, it seems fairly simple to me, it splits the input
date (given format) into the three sections, and it works great, I
have no idea how to attain the same resutls with std::string

Look:

#include <string>
#include <sstream>
#include <iostream>

void process(const std::string& date)
{
std::istringstream tok(date);

std::string month, day, year;
tok >> month >> day >> year;

std::string century = year.substr(0,2);
std::string year2 = year.substr(2,4);
}

int main()
{
std::cout << "Enter a date (ex. Feb 27 2008): ";

std::string date;
std::getline(std::cin, date);

process(date);
}

Add error checking as needed.

The FAQ covers the convertion from string to ints:
http://www.parashift.com/c++-faq-lite/misc-technical-issues.html
 
H

happyasaclam111

Default said:
year[2] = '/0';
Damn it! '\0', of course.

Bummer, just when i thought I was G2G..this code:

d = (year[2] = '\0');

equates to 0 no matter what year!
year[2] is a char. I believe what you wrote is similar to saying:
char c;
int d = c = 0;

For mostly historical reasons, chars can be assigned to ints and back
again without a cast or even a warning from the compiler.

The whole point of the year[2] = '\0' is so that any function that you
pass 'year' to will "think" that the string is only 2 characters
long. In C, you generally pass a string as a char* (pointer to char),
which contains no information about length - it is only a memory
address. Since '\0' is not a "valid" character, it is used to
terminate strings. Otherwise, a function-writer would have no idea
when to stop processing a string.

When you pass "year" to a function, you are saying "this is the
address that my character array starts on. Process it until you reach
a null character ('\0')" When you pass "year + 2" you are doing the
same thing only you aren't passing the address it starts on, you are
passing the address two sizeof(char) bytes past where the array
starts.

The I/O functions provided by the standard library automatically
append a null character at the end of a string. String literals also
have a null character appended, so:

char* c = "Hello"; /* Sets aside 6 sizeof(char) bytes of memory H E L
L O \0 */

After you have inserted the null-terminator you can process the
information just like you did to get the last two digits (except for
the + 2 business).

That said, if you don't want to mess up the 'year' array, you might
just want to copy the first two characters into a new array.

In the real world, I don't know why anyone would actually use the C-
string functions if they could possibly avoid it. Generally the C++
container std::string is much more practical and can be very cheap in
terms of computer resources. However, I think that learning to deal
with character arrays might be the best way to learn about pointers -
knowledge that will be very important for real applications.

Hope this helps. Best of luck.
 
D

Daniel T.

yogi_bear_79 said:
yogi_bear_79 wrote:
char *year = strtok_s(NULL, "\0", &nextToken);

There's no standard function called strtok_s(). As such, I can't
comment on whether what you have works. I suspect you're not showing us
all the code.
c = atoi(year+2);
The above code c = atoi(year+2); was suggested to me to help turn the
Char* into an int and only keep the last two characters. Now I need to
do the same thing but only keep the first two.  I'd like a reference
on the +2 part, as this is the part I didn't know about.  Since I
assume the code to display the first two digits would be similar I
would like a reference on what was done here.  Thanks

No, it wouldn't. The easiest way, given a modifiable buffer, would be;

year[2] = '/0';

Don't use atoi() unless you know for sure that the string represents an
number that fits in an int.

Better yet is the advice you were given before, use std::string and
such. You have no real knowledge of C-style strings, so why are trying
to use them?

Brian


The entire code is:

The below is obviously not the entire code. "longDate" isn't defined and
the code isn't contained in a function. :)
char* nextToken;
int a, b, c, d;

char *month = strtok_s(longDate, " ", &nextToken);
char *day = strtok_s(NULL, " ", &nextToken);
char *year = strtok_s(NULL, "\0", &nextToken);

c = atoi(year+2);//returns the last two digits from char *year
d = atoi(year); //need to be modified to return the first two digits.

I am in a distant learning enviornment, this is only a simple lab, the
input data is controlled, thus I know exactly what will be in my
string to start with. We are not to std:string yet, or even error
handleing. While I agree there are certainly better ways to do
things, in this instance this is what is required.

I've been following many of your questions during this lab. Those of us
who harp on you to use string and other standard components are using
the entire language to create the optimal solution. Unfortunately, you
are limited to a subset of the language that your teacher has seen fit
to cover.

The biggest problem though is that your teacher has given you a problem
that is not optimally solved using the subset of the language he has
covered, and we don't know what that subset is. I consider this a fault
of your teacher, maybe he is new at his job, or maybe he doesn't know
C++ very well himself. Whatever the reason, you are getting a
sub-standard education, and that is a shame. :-(

I think you would benefit by posting the problem statement here and see
what kinds of solutions are presented... If you are serious about
learning C++ that is.
 
M

Michael DOUBEZ

yogi_bear_79 a écrit :
char *year = strtok_s(NULL, "\0", &nextToken);
c = atoi(year+2);


The above code c = atoi(year+2); was suggested to me to help turn the
Char* into an int and only keep the last two characters. Now I need to
do the same thing but only keep the first two. I'd like a reference
on the +2 part, as this is the part I didn't know about. Since I
assume the code to display the first two digits would be similar I
would like a reference on what was done here. Thanks

If you have validated that year as the format "dddd" where d are digits,
you could switch to a sscanf call. IMO it is safe enough in this case

char* year="2008";
int year_head,year_tail;
int nb_read=sscanf(year,"%2d%2d",&year_head,&year_tail);
if(nb_read!=2)
{//format error
//...
}

Note: the field length (the 2 in %2d) are maximal field size. That means
that processing "208" will give you the same result as "2008".

Michael
 
R

Ron Natalie

Christopher said:
1 Do not use char* for text. Use std::string instead
2 Do not use ato_anything_ or _anything_toa functions. Use a
std::stringstream for conversions instead
3 The <ctime> header already has everything you may need for time and
date objects and the C++ streams already know how to translate them to
text and provide formatting for you.
strtok sucks as well.
 
D

Default User

Ron Natalie wrote:

strtok sucks as well.


It is a tricky function to use correctly. Its main difficulty is that
it modifies the string it operates on, so string literals can't be
passed in safely. Unless you really know what you are doing, it's best
to pass this one by.

In most cases, a state machine machine to process the string or use of
strchr() is best for "C" style work. C++ is best with sstream.





Brian
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,271
Latest member
BuyAtenaLabsCBD

Latest Threads

Top