How do I call a function taking only "const char *a"

Discussion in 'C Programming' started by RoughRyde, Dec 14, 2006.

  1. RoughRyde

    RoughRyde Guest

    Hi all,

    I'm totally new to C and hava a problem how to handle different types
    of variables.

    I have a function which which you call by:

    double calcdiff(const char *old, const char *new)

    I have at start two doubles that I need to convert in order to call the
    above function. How would I go about to do that?

    Thanks
     
    RoughRyde, Dec 14, 2006
    #1
    1. Advertising

  2. RoughRyde

    Chris Dollin Guest

    RoughRyde wrote:

    > I'm totally new to C and hava a problem how to handle different types
    > of variables.


    [Get a decent C book. Dripfeeding via newsgroup is slow.]

    > I have a function which which you call by:
    >
    > double calcdiff(const char *old, const char *new)


    You have a function called `calcdiff` which returns a `double` and
    it takes two /strings/ as arguments?

    Something is broken.

    > I have at start two doubles that I need to convert in order to call the
    > above function. How would I go about to do that?


    If you want to get the string representation of a double value,
    probably you should use `sprintf`. But I'd apply the Birmingham
    principle [1] first. If `calcdiff` takes two strings representing
    doubles, turns them into doubles, subtracts them, and returns the
    result, then it's a pretty naff function (and if it doesn't, it's
    been given a naff name: heads you lose, tails I win).

    [1] "I wouldn't start from here."

    --
    Chris "Perikles triumphant" Dollin
    "Who do you serve, and who do you trust?" /Crusade/
     
    Chris Dollin, Dec 14, 2006
    #2
    1. Advertising

  3. "RoughRyde" <> wrote in message
    news:...
    > Hi all,
    >
    > I'm totally new to C and hava a problem how to handle different types
    > of variables.
    >
    > I have a function which which you call by:
    >
    > double calcdiff(const char *old, const char *new)
    >
    > I have at start two doubles that I need to convert in order to call the
    > above function. How would I go about to do that?
    >
    > Thanks
    >

    You haven't given enough information. What does the function actually
    do? What format are the inputs supposed to be in?

    For example:

    d = calcdiff( "3.555", "1.7E-16" );

    or

    d = calcdiff( "three and a half", "pi" );

    If it is just the former, and the function does exactly what its name
    implies, why don't you just use:

    d = var1 - var2;

    --
    Fred L. Kleinschmidt
    Boeing Associate Technical Fellow
    Technical Architect, Software Reuse Project
     
    Fred Kleinschmidt, Dec 14, 2006
    #3
  4. RoughRyde

    RoughRyde Guest

    What I want is to calculate the number of days between two dates.
    Given my limited knowledge of C I found an example of this on the web
    which looked as below. The problem is that I'm given indata as doubles.
    So in order to take the easy way out I just wanted to convert those
    doubles.

    But if you have any other suggestions on how to solve this that's
    appreciated.



    double calcdiff(const char *old, const char *new)
    {
    struct tm t1 = {0};
    struct tm t2 = {0};
    time_t tt1 = {0};
    time_t tt2 = {0};

    stotm(&t1, old);
    stotm(&t2, new);
    tt1 = mktime(&t1);
    tt2 = mktime(&t2);
    if(tt1 != -1 && tt2 != -1)
    {
    long day = 0;
    double d = difftime(tt1, tt2);
    if(d < 0) d *= -1.0;
    day = d / 86400;
    return day;
    }
    else
    {
    return 0;
    }

    }

    void stotm(struct tm *p, const char *s)
    {
    int i;
    struct tm blank = {0};
    *p = blank;

    for(i = 0; i < 4; i++)
    {
    p->tm_year *= 10;
    p->tm_year += *s++ - '0';
    }
    p->tm_year -= 1900;
    for(i = 0; i < 2; i++)
    {
    p->tm_mon *= 10;
    p->tm_mon += *s++ - '0';
    }
    --p->tm_mon;
    p->tm_mday = 10 * (*s++ - '0');
    p->tm_mday += *s++ - '0';

    }



    Fred Kleinschmidt skrev:

    > "RoughRyde" <> wrote in message
    > news:...
    > > Hi all,
    > >
    > > I'm totally new to C and hava a problem how to handle different types
    > > of variables.
    > >
    > > I have a function which which you call by:
    > >
    > > double calcdiff(const char *old, const char *new)
    > >
    > > I have at start two doubles that I need to convert in order to call the
    > > above function. How would I go about to do that?
    > >
    > > Thanks
    > >

    > You haven't given enough information. What does the function actually
    > do? What format are the inputs supposed to be in?
    >
    > For example:
    >
    > d = calcdiff( "3.555", "1.7E-16" );
    >
    > or
    >
    > d = calcdiff( "three and a half", "pi" );
    >
    > If it is just the former, and the function does exactly what its name
    > implies, why don't you just use:
    >
    > d = var1 - var2;
    >
    > --
    > Fred L. Kleinschmidt
    > Boeing Associate Technical Fellow
    > Technical Architect, Software Reuse Project
     
    RoughRyde, Dec 14, 2006
    #4
  5. RoughRyde

    Ernie Wright Guest

    RoughRyde wrote:

    > What I want is to calculate the number of days between two dates.
    > Given my limited knowledge of C I found an example of this on the web
    > which looked as below. The problem is that I'm given indata as doubles.


    What do the doubles contain? Without knowing that, it's pretty hard to
    suggest what might work better.

    Based on the code you posted, let's pretend that the doubles you're
    given represent a date as

    10000 * year + 100 * month + day

    so that today's date would be 20061214.0. If that's the case, you can
    replace the stotm() function with something like this,

    void dtotm( struct tm *t, double d )
    {
    memset( t, 0, sizeof( *t ));
    t->tm_year = ( int ) d / 10000 - 1900;
    t->tm_mon = ( int ) fmod( d, 10000 ) / 100 - 1;
    t->tm_mday = ( int ) fmod( d, 100 );
    }

    Change calcdiff() to accept double arguments rather than strings, and
    replace calls to stotm() with dtotm().

    But now you have another problem. If either of the dates is before
    January 1, 1970, calcdiff() will fail. In many implementations, it'll
    also fail if either date is after January 18, 2038. This is the range
    of dates that can typically be stored in a value of type time_t.

    If you need to work with dates outside this range, consider converting
    them to Julian day numbers. This is the number of days since January 1,
    4713 B.C. Today is JD 2454084, for example. You can subtract these
    numbers directly to find the number of days between two dates. Code for
    converting to JD is easily googled.

    - Ernie http://home.comcast.net/~erniew
     
    Ernie Wright, Dec 14, 2006
    #5
  6. Ernie Wright <> writes:
    [...]
    > Based on the code you posted, let's pretend that the doubles you're
    > given represent a date as
    >
    > 10000 * year + 100 * month + day
    >
    > so that today's date would be 20061214.0. If that's the case, you can
    > replace the stotm() function with something like this,
    >
    > void dtotm( struct tm *t, double d )
    > {
    > memset( t, 0, sizeof( *t ));
    > t->tm_year = ( int ) d / 10000 - 1900;
    > t->tm_mon = ( int ) fmod( d, 10000 ) / 100 - 1;
    > t->tm_mday = ( int ) fmod( d, 100 );
    > }
    >
    > Change calcdiff() to accept double arguments rather than strings, and
    > replace calls to stotm() with dtotm().
    >
    > But now you have another problem. If either of the dates is before
    > January 1, 1970, calcdiff() will fail. In many implementations, it'll
    > also fail if either date is after January 18, 2038. This is the range
    > of dates that can typically be stored in a value of type time_t.


    Typically, but not always. *Many* systems use a time_t representation
    in which 0 represents January 1, 1970, but this is not specified in
    the C standard. The standard says only that time_t is an arithmetic
    type capable of representing times.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Dec 14, 2006
    #6
  7. RoughRyde

    Ernie Wright Guest

    Keith Thompson wrote:

    > *Many* systems use a time_t representation in which 0 represents
    > January 1, 1970, but this is not specified in the C standard. The
    > standard says only that time_t is an arithmetic type capable of
    > representing times.


    Thanks for the clarification.

    It looks like the standard does *not* specify

    the resolution (usually 1 second),
    the epoch (the meaning of (time_t) 0, usually January 1, 1970),
    a maximum time_t value (often LONG_MAX),
    whether time_t is signed (whether (time_t) -1 is meaningful),
    or whether a time_t is aligned to a standard time scale (e.g. UTC).

    I'm a little surprised it's that vague.

    - Ernie http://home.comcast.net/~erniew
     
    Ernie Wright, Dec 15, 2006
    #7
  8. RoughRyde

    CBFalconer Guest

    Ernie Wright wrote:
    > Keith Thompson wrote:
    >
    >> *Many* systems use a time_t representation in which 0 represents
    >> January 1, 1970, but this is not specified in the C standard. The
    >> standard says only that time_t is an arithmetic type capable of
    >> representing times.

    >
    > Thanks for the clarification.
    >
    > It looks like the standard does *not* specify
    >
    > the resolution (usually 1 second),
    > the epoch (the meaning of (time_t) 0, usually January 1, 1970),
    > a maximum time_t value (often LONG_MAX),
    > whether time_t is signed (whether (time_t) -1 is meaningful),
    > or whether a time_t is aligned to a standard time scale (e.g. UTC).
    >
    > I'm a little surprised it's that vague.


    Why should you be surprised? When the standard was promulgated any
    further specification of those items would have broken existing
    code, and it was a specific objective to minimize such breakage.
    It is always possible to wrap the standard in more restrictive
    standards, e.g. Posix, but not to relax things.

    Read the C99 Rationale (N897.pdf) which includes much of the C90
    rationale.

    --
    Chuck F (cbfalconer at maineline dot net)
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net>
     
    CBFalconer, Dec 15, 2006
    #8
  9. Ernie Wright <> writes:
    > Keith Thompson wrote:
    >> *Many* systems use a time_t representation in which 0 represents
    >> January 1, 1970, but this is not specified in the C standard. The
    >> standard says only that time_t is an arithmetic type capable of
    >> representing times.

    >
    > Thanks for the clarification.
    >
    > It looks like the standard does *not* specify
    >
    > the resolution (usually 1 second),
    > the epoch (the meaning of (time_t) 0, usually January 1, 1970),
    > a maximum time_t value (often LONG_MAX),
    > whether time_t is signed (whether (time_t) -1 is meaningful),
    > or whether a time_t is aligned to a standard time scale (e.g. UTC).
    >
    > I'm a little surprised it's that vague.


    It's vaguer than that. There's no guarantee that time_t is an integer
    type, or that the relationship between time_t values and actual time
    is linear, or even that it's monotonic (i.e., that increasing time_t
    values represent increasing times).

    To take just one example, a conforming implementation could represent
    the current time (2006-12-15 08:27:23 UTC) as the integer value
    20061215082723 or as the floating-point value 20061215.082723. Or it
    could use ranges of bits, rather than of decimal digits, to represent
    the various fields. And so on.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Dec 15, 2006
    #9
  10. RoughRyde

    Ernie Wright Guest

    CBFalconer wrote:

    > Ernie Wright wrote:
    >
    >> I'm a little surprised [the standard re time_t is] that vague.

    >
    > Why should you be surprised?


    Partly ignorance. Not knowing what the standard said about it, I've
    assumed it was along the lines of what POSIX says about it.

    But also partly because, unless it's wrapped in something more rigorous
    like POSIX, it can't be used portably and is almost useless. To quote
    one example from the rationale,

    Since no measure is given for how precise an implementation’s best
    approximation to the current time must be, an implementation could
    always return the same date [from time()] instead of a more honest
    –1. This is, of course, not the intent.

    And throw in Keith Thompson's observations here as well.

    Basically, without knowing anything about the precision or the range,
    you can't portably rely on time() and mktime() to do anything at all.

    Correction to my previous post: time_t must be signed (in some vague
    sense: it must be able to represent (time_t) -1), but since this is
    used as an error return by time() and mktime(), as a practical matter it
    usually cannot represent times before its epoch ((time_t) 0).

    - Ernie http://home.comcast.net/~erniew
     
    Ernie Wright, Dec 15, 2006
    #10
  11. Ernie Wright <> writes:
    [...]
    > Correction to my previous post: time_t must be signed (in some vague
    > sense: it must be able to represent (time_t) -1), but since this is
    > used as an error return by time() and mktime(), as a practical matter it
    > usually cannot represent times before its epoch ((time_t) 0).


    No, the value -1 can be converted to any arithmetic type, and the
    result is always well defined. If time_t is, say, an unsigned 32-bit
    integer, then (time_t)-1 has the value 2147483647.

    There are good reasons to make time_t signed, as you point out, so it
    can represent times before the epoch (whatever the epoch happens to
    be, and assuming a direct relationship between time_t values and
    actual times).

    I wouldn't mind seeing the specification nailed down a bit in the next
    standard. I suspect (though I'm not certain) that things could be
    tightened up significantly without affecting any existing
    implementations. Better, there should probably be a whole new time
    interface without the holes in the current one (I think there was an
    attempt to introduce such an interface for C99, but it wasn't ready in
    time.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Dec 15, 2006
    #11
  12. RoughRyde

    Ernie Wright Guest

    Keith Thompson wrote:

    > Ernie Wright <> writes:
    >
    >> Correction to my previous post: time_t must be signed (in some vague
    >> sense: it must be able to represent (time_t) -1), but since this is
    >> used as an error return by time() and mktime(), as a practical matter
    >> it usually cannot represent times before its epoch ((time_t) 0).

    >
    > No, the value -1 can be converted to any arithmetic type, and the
    > result is always well defined. If time_t is, say, an unsigned 32-bit
    > integer, then (time_t)-1 has the value 2147483647.


    Pretty sure it has the value 4294967295.

    More importantly, I'm not sure what your "no" is in response to. If the
    underlying representation is unsigned, it ipso facto doesn't provide any
    obvious way of encoding dates prior to the epoch. If signed, there is
    at least one date prior to the epoch that collides with a value reserved
    to indicate an error. In both cases, it is "signed" in the sense that
    it must be capable of representing a value that is portably expressible
    in only one way: (time_t) -1.

    The definition of time_t is so flaccid that all kinds of *un*obvious
    encodings are valid, which is why I qualified what I wrote with phrases
    like "in some vague sense" and "as a practical matter." Without those
    qualifications, it would be difficult to say anything at all about what
    a time_t can represent.

    - Ernie http://home.comcast.net/~erniew
     
    Ernie Wright, Dec 17, 2006
    #12
  13. Ernie Wright <> writes:
    > Keith Thompson wrote:
    >
    >> Ernie Wright <> writes:
    >>
    >>> Correction to my previous post: time_t must be signed (in some vague
    >>> sense: it must be able to represent (time_t) -1), but since this is
    >>> used as an error return by time() and mktime(), as a practical matter
    >>> it usually cannot represent times before its epoch ((time_t) 0).

    >> No, the value -1 can be converted to any arithmetic type, and the
    >> result is always well defined. If time_t is, say, an unsigned 32-bit
    >> integer, then (time_t)-1 has the value 2147483647.

    >
    > Pretty sure it has the value 4294967295.


    D'oh! You're right, of course.

    > More importantly, I'm not sure what your "no" is in response to. If the
    > underlying representation is unsigned, it ipso facto doesn't provide any
    > obvious way of encoding dates prior to the epoch. If signed, there is
    > at least one date prior to the epoch that collides with a value reserved
    > to indicate an error. In both cases, it is "signed" in the sense that
    > it must be capable of representing a value that is portably expressible
    > in only one way: (time_t) -1.
    >
    > The definition of time_t is so flaccid that all kinds of *un*obvious
    > encodings are valid, which is why I qualified what I wrote with phrases
    > like "in some vague sense" and "as a practical matter." Without those
    > qualifications, it would be difficult to say anything at all about what
    > a time_t can represent.


    The "No" was in response to "time_t must be signed"; I should have
    paid more attention to the following "in some vague sense". I don't
    think of unsigned integer types as being "signed in some vague sense",
    but I see what you mean.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Dec 17, 2006
    #13
  14. RoughRyde

    Ernie Wright Guest

    Keith Thompson wrote:

    > The "No" was in response to "time_t must be signed"; I should have
    > paid more attention to the following "in some vague sense". I don't
    > think of unsigned integer types as being "signed in some vague sense",
    > but I see what you mean.


    I probably wouldn't have put it exactly that way if I hadn't been in
    mid-backpedal.

    Thanks for the discussion. I hadn't looked very carefully at time_t
    until now, and it was an eye-opener.

    - Ernie http://home.comcast.net/~erniew
     
    Ernie Wright, Dec 17, 2006
    #14
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Kevin
    Replies:
    6
    Views:
    3,887
    Oliver Wong
    Feb 22, 2006
  2. grbgooglefan
    Replies:
    2
    Views:
    430
    Pascal Bourguignon
    Jan 30, 2008
  3. Jim Cain
    Replies:
    1
    Views:
    209
    Yukihiro Matsumoto
    Jul 18, 2003
  4. Dylan Lukes
    Replies:
    5
    Views:
    101
    Robert Klemme
    Nov 21, 2009
  5. Steve Swift
    Replies:
    7
    Views:
    113
    Steve Swift
    Jul 20, 2008
Loading...

Share This Page