calculate value between two strings

Discussion in 'C Programming' started by John Green, Oct 23, 2010.

  1. John Green

    John Green Guest

    Hi,

    I would like to calculate the value between two strings. For example:
    abc-aaa would be 29.

    I tried:
    printf("abc-aaa = %d\n","abc"-"aaa");
    but I get -4.

    How can I do what I want?

    Thanks,
     
    John Green, Oct 23, 2010
    #1
    1. Advertising

  2. John Green

    Ian Collins Guest

    On 10/24/10 09:51 AM, John Green wrote:
    > Hi,
    >
    > I would like to calculate the value between two strings. For example:
    > abc-aaa would be 29.
    >
    > I tried:
    > printf("abc-aaa = %d\n","abc"-"aaa");
    > but I get -4.


    So the address of "abc" is 4 less than the address of "aaa", which isn't
    surprising.

    > How can I do what I want?


    What do you want?

    --
    Ian Collins
     
    Ian Collins, Oct 23, 2010
    #2
    1. Advertising

  3. John Green

    Eric Sosman Guest

    On 10/23/2010 4:51 PM, John Green wrote:
    > Hi,
    >
    > I would like to calculate the value between two strings. For example:
    > abc-aaa would be 29.


    Did you mean 28? I'm going to assume that you want to treat
    each string as a base-26 number with digits a=0,...,z=25; if that's
    not your intent, please explain it more fully.

    > I tried:
    > printf("abc-aaa = %d\n","abc"-"aaa");
    > but I get -4.


    You might have gotten almost anything, including herpes.

    > How can I do what I want?


    A couple of ways, depending on what you already know about the
    strings (e.g., will they always be of the same length, are they known
    to be free of strange characters like '#', do you treat 'A' and 'a'
    as equivalent, and so on). Here are a few sketches:

    1) If the strings will always be of the same length, you could
    march across them from left to right, comparing corresponding
    characters. You'd find 'a'-'a' == 0, so you'd set delta=0.
    At the next position you'd have 'b'-'a' == 1, and you'd set
    delta = delta * 26 + 1 == 1. In the third position you'd get
    'c'-'a' == 2, delta = delta * 26 + 2 == 28. Since the strings
    are now exhausted, that's your final answer.

    2) Method (1) has a flaw, because it assumes 'b'-'a' == 'c'-'b'
    == ... == 'z'-'y' == 1. This is a very common scheme for
    encoding letter values, but it is not universal. You could
    salvage the method by looking up each character in a separate
    string "abcdefghijklmnopqrstuvwxyz" and subtracting their
    positions rather than their code values. The strchr() function
    could be your friend here, and there are other possibilities too.

    3) If the strings are of unequal length, you could pretend that the
    shorter had a prefix of "aaa...aaa" to extend it to the length
    of the longer. In this case it might be easier to work from
    right to left and accumulate delta a little differently.

    4) A sneaky possibility: The strtol() function can be made to
    treat the string as a base-36 number, with a=10,...,z=35. You
    could convert each string to a number this way, subtract them,
    and then fiddle with the answer to correct the 36-vs-26 bias.
    This approach treats 'A' and 'a' as the same.

    5) All the above methods assume that the strings are not "too long."
    If they get long enough so that their values or differences
    exceed the capacity of your machine's numbers, you'll need to get
    more imaginative. For most machines strings of up to length 6
    will be all right, while longer strings may encounter trouble.
    With very little effort you could push the upper limit to 13, but
    beyond that you'd have a good deal more work to do.

    However, I have a sneaking suspicion that your current level of
    expertise in C might not be adequate for any of these approaches. This
    is not a slight on your character (there's no shame in starting to learn
    something new to you), but I really, really think you should spend some
    more time with your C textbook before you try to go much further.

    --
    Eric Sosman
    lid
     
    Eric Sosman, Oct 23, 2010
    #3
  4. John Green <> writes:
    > I would like to calculate the value between two strings. For example:
    > abc-aaa would be 29.
    >
    > I tried:
    > printf("abc-aaa = %d\n","abc"-"aaa");
    > but I get -4.
    >
    > How can I do what I want?


    Start by clearly defining what you want.

    C defines the difference between two numbers (it's simple
    subtraction, though with some odd characteristics when you consider
    overflow and/or unsigned types). It also defines the difference
    between two pointer values (which is what your program happens
    to be doing, but in a way that's several kinds of incorrect).
    And you can subtract an integer from a pointer value, yielding a
    new pointer value, but that's not what you want either.

    You've shown us an example, "abc-aaa would be 29", which has led
    some posters to speculate on what you might mean (which leads to a
    result of 28, not 29). But that's only a guess. Another perfectly
    plausible meaning, given the arguments "abc" and "aaa", would be
    to treat both strings as hexadecimal representations, yielding 18
    in this case.

    Or, since you said "the value between two strings" rather than
    "the difference between two strings", and string values can be
    meaningfully ordered by strcmp(), the result could be anything from
    "aab" to "abb", or even "aaazzzzzzzzzzzzzql" for that matter.

    There is no obvious meaning for "the value between two strings",
    and a single example isn't enough to specify one. It's up to you
    to define (preferably not just by example) exactly what you mean.
    Not only does it make it a lot easier for us to help you, it goes
    a long way towards writing a solution in C. If you can write a
    good English description of what you want to compute, you may be
    able to translate that description into C.

    Recommended reading:
    http://www.catb.org/~esr/faqs/smart-questions.html

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Oct 23, 2010
    #4
  5. John Green

    Eyegor Guest

    On Oct 23, 6:30 pm, Keith Thompson <> wrote:
    > John Green <> writes:
    > > I would like to calculate the value between two strings.  For example:
    > > abc-aaa would be 29.

    >
    > > I tried:
    > > printf("abc-aaa = %d\n","abc"-"aaa");
    > > but I get -4.

    >
    > > How can I do what I want?

    >
    > Start by clearly defining what you want.
    >
    > C defines the difference between two numbers (it's simple
    > subtraction, though with some odd characteristics when you consider
    > overflow and/or unsigned types).  It also defines the difference
    > between two pointer values (which is what your program happens
    > to be doing, but in a way that's several kinds of incorrect).
    > And you can subtract an integer from a pointer value, yielding a
    > new pointer value, but that's not what you want either.
    >
    > You've shown us an example, "abc-aaa would be 29", which has led
    > some posters to speculate on what you might mean (which leads to a
    > result of 28, not 29).  But that's only a guess.  Another perfectly
    > plausible meaning, given the arguments "abc" and "aaa", would be
    > to treat both strings as hexadecimal representations, yielding 18
    > in this case.
    >
    > Or, since you said "the value between two strings" rather than
    > "the difference between two strings", and string values can be
    > meaningfully ordered by strcmp(), the result could be anything from
    > "aab" to "abb", or even "aaazzzzzzzzzzzzzql" for that matter.
    >
    > There is no obvious meaning for "the value between two strings",
    > and a single example isn't enough to specify one.  It's up to you
    > to define (preferably not just by example) exactly what you mean.
    > Not only does it make it a lot easier for us to help you, it goes
    > a long way towards writing a solution in C.  If you can write a
    > good English description of what you want to compute, you may be
    > able to translate that description into C.
    >
    > Recommended reading:http://www.catb.org/~esr/faqs/smart-questions.html
    >
    > --
    > Keith Thompson (The_Other_Keith)  <http://www.ghoti.net/~kst>
    > Nokia
    > "We must do something.  This is something.  Therefore, we must do this."
    >     -- Antony Jay and Jonathan Lynn, "Yes Minister"


    Assuming your string variables are of the same length SL and your
    strings are LSB aligned you can do the flowing:

    X=0
    for(i=SL; i--; i>0){
    X=X+(S1-S2)*26^(SL-i-1);
    }
    By default your strings are MSB aligned, so you have to create 2
    strings, fill them with "nulls" and strcopy the input strings to the
    most right section of addresses of the S1 and S2 buffers. SL is the
    size in bytes of S1 and S2 Buffers.
     
    Eyegor, Oct 24, 2010
    #5
  6. John Green

    Eyegor Guest

    On Oct 23, 7:31 pm, Eyegor <> wrote:
    > On Oct 23, 6:30 pm, Keith Thompson <> wrote:
    >
    >
    >
    > > John Green <> writes:
    > > > I would like to calculate the value between two strings.  For example:
    > > > abc-aaa would be 29.

    >
    > > > I tried:
    > > > printf("abc-aaa = %d\n","abc"-"aaa");
    > > > but I get -4.

    >
    > > > How can I do what I want?

    >
    > > Start by clearly defining what you want.

    >
    > > C defines the difference between two numbers (it's simple
    > > subtraction, though with some odd characteristics when you consider
    > > overflow and/or unsigned types).  It also defines the difference
    > > between two pointer values (which is what your program happens
    > > to be doing, but in a way that's several kinds of incorrect).
    > > And you can subtract an integer from a pointer value, yielding a
    > > new pointer value, but that's not what you want either.

    >
    > > You've shown us an example, "abc-aaa would be 29", which has led
    > > some posters to speculate on what you might mean (which leads to a
    > > result of 28, not 29).  But that's only a guess.  Another perfectly
    > > plausible meaning, given the arguments "abc" and "aaa", would be
    > > to treat both strings as hexadecimal representations, yielding 18
    > > in this case.

    >
    > > Or, since you said "the value between two strings" rather than
    > > "the difference between two strings", and string values can be
    > > meaningfully ordered by strcmp(), the result could be anything from
    > > "aab" to "abb", or even "aaazzzzzzzzzzzzzql" for that matter.

    >
    > > There is no obvious meaning for "the value between two strings",
    > > and a single example isn't enough to specify one.  It's up to you
    > > to define (preferably not just by example) exactly what you mean.
    > > Not only does it make it a lot easier for us to help you, it goes
    > > a long way towards writing a solution in C.  If you can write a
    > > good English description of what you want to compute, you may be
    > > able to translate that description into C.

    >
    > > Recommended reading:http://www.catb.org/~esr/faqs/smart-questions.html

    >
    > > --
    > > Keith Thompson (The_Other_Keith)  <http://www.ghoti.net/~kst>
    > > Nokia
    > > "We must do something.  This is something.  Therefore, we must do this."
    > >     -- Antony Jay and Jonathan Lynn, "Yes Minister"

    >
    > Assuming your string variables are of the same length SL and your
    > strings are LSB aligned you can do the flowing:
    >
    > X=0
    > for(i=SL; i--; i>0){
    > X=X+(S1-S2)*26^(SL-i-1);}
    >
    > By default your strings are MSB aligned, so you have to create 2
    > strings, fill them with "nulls" and strcopy the input strings to the
    > most right section of addresses of the S1 and S2 buffers. SL is the
    > size in bytes of S1 and S2 Buffers.


    I know i used ^ as power, which is a no-no, but i got lazy.
     
    Eyegor, Oct 24, 2010
    #6
  7. Eyegor <> writes:
    > On Oct 23, 6:30 pm, Keith Thompson <> wrote:
    >> John Green <> writes:
    >> > I would like to calculate the value between two strings.  For example:
    >> > abc-aaa would be 29.

    [...]
    >> > How can I do what I want?

    >>
    >> Start by clearly defining what you want.

    [...]
    > Assuming your string variables are of the same length SL and your
    > strings are LSB aligned you can do the flowing:
    >
    > X=0
    > for(i=SL; i--; i>0){
    > X=X+(S1-S2)*26^(SL-i-1);
    > }
    > By default your strings are MSB aligned, so you have to create 2
    > strings, fill them with "nulls" and strcopy the input strings to the
    > most right section of addresses of the S1 and S2 buffers. SL is the
    > size in bytes of S1 and S2 Buffers.


    What??

    You already acknowledged that "^" is xor, not exponentation. But what's
    all this about the strings being "MSB aligned" or "LSB aligned"? As far
    as I can tell, it just doesn't make any sense.

    Given:
    char s[] = "abc";
    s[0] == 'a', s[1] == 'b', s[2] == 'c', and s[3] == '\0'. There's
    no alignment to consider.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Oct 24, 2010
    #7
  8. Keith Thompson <> writes:

    > Eyegor <> writes:
    >> On Oct 23, 6:30 pm, Keith Thompson <> wrote:
    >>> John Green <> writes:
    >>> > I would like to calculate the value between two strings.  For example:
    >>> > abc-aaa would be 29.

    > [...]
    >>> > How can I do what I want?
    >>>
    >>> Start by clearly defining what you want.

    > [...]
    >> Assuming your string variables are of the same length SL and your
    >> strings are LSB aligned you can do the flowing:
    >>
    >> X=0
    >> for(i=SL; i--; i>0){
    >> X=X+(S1-S2)*26^(SL-i-1);
    >> }
    >> By default your strings are MSB aligned, so you have to create 2
    >> strings, fill them with "nulls" and strcopy the input strings to the
    >> most right section of addresses of the S1 and S2 buffers. SL is the
    >> size in bytes of S1 and S2 Buffers.

    >
    > What??
    >
    > You already acknowledged that "^" is xor, not exponentation. But what's
    > all this about the strings being "MSB aligned" or "LSB aligned"? As far
    > as I can tell, it just doesn't make any sense.


    Following Seebs's advice, one might ask what could this notion of
    alignment be since it clearly is not C's notion of it. I am pretty sure
    that the OP means "lined up" rather than any C-like notion of alignment.

    It's not easy to get to this conclusion because that condition is
    redundant. Once the OP has said that the string must be the same
    length, then their LSBs will "line up". Furthermore, when the OP says
    "nulls" he means "whatever character is used to represent zero".
    I.e. you must pad the shorter string with 'a's on the left.

    The whole thing is a mess. Not only is there a ^ in place of pow(), but
    the 'for' loop looks all wrong despite the fact that it works fine with
    it's pointless third clause. The alignment condition uses the wrong
    words and is redundant. There is no need to create 2 strings (you don't
    need any in fact but, as described, the algorithm needs at more one of
    them to be copied) and the padding with "nulls" is not right.

    Oddly though, despite all that, I understood exactly what the OP meant
    on first reading! I suppose that comes from years of looking at
    students' programs.

    <snip>
    --
    Ben.
     
    Ben Bacarisse, Oct 24, 2010
    #8
  9. On Sun, 24 Oct 2010 08:00:12 +0200, "io_x" <> wrote:

    >
    >"io_x" <> ha scritto nel messaggio
    >news:4cc3bed2$0$26698$...
    >>
    >> "John Green" <> ha scritto nel messaggio
    >> news:...


    snip

    >
    >/*-1 for error */
    >unsigned value(char* a)
    >{int i;
    > unsigned tot;
    >
    > if(a==0) return -1;


    value() returns an unsigned. -1 will be converted to UINT_MAX.

    > for(i=0, tot=0; i>=0 && a; ++i)


    i starts at 0. i is incremented but never decremented. Does the test
    i>=0 ever evaluate to 0?

    > {tot+=a;
    > if((int)tot<0) return -1;


    tot is unsigned. It cannot be negative. (int)tot must be
    non-negative if the value is between 0 and INT_MAX. If the value
    exceeds INT_MAX, it can be negative only if that is the documented
    implementation specific behavior. Do you know of any implementations
    that do so? Will the test ever portably evaluate to 1?

    > }
    > if(i<0) return -1;


    When will this test ever evaluate to 1?

    > return tot;
    >}
    >


    Or was it your intent to teach the OP as many bad ideas as possible?

    --
    Remove del for email
     
    Barry Schwarz, Oct 24, 2010
    #9
  10. John Green

    Chad Guest

    On Oct 23, 2:19 pm, Eric Sosman <> wrote:
    > On 10/23/2010 4:51 PM, John Green wrote:
    >
    > > Hi,

    >
    > > I would like to calculate the value between two strings.  For example:
    > > abc-aaa would be 29.

    >
    >      Did you mean 28?  I'm going to assume that you want to treat
    > each string as a base-26 number with digits a=0,...,z=25; if that's
    > not your intent, please explain it more fully.
    >
    > > I tried:
    > > printf("abc-aaa = %d\n","abc"-"aaa");
    > > but I get -4.

    >
    >      You might have gotten almost anything, including herpes.
    >
    > > How can I do what I want?

    >
    >      A couple of ways, depending on what you already know about the
    > strings (e.g., will they always be of the same length, are they known
    > to be free of strange characters like '#', do you treat 'A' and 'a'
    > as equivalent, and so on).  Here are a few sketches:
    >
    >     1) If the strings will always be of the same length, you could
    >        march across them from left to right, comparing corresponding
    >        characters.  You'd find 'a'-'a' == 0, so you'd set delta=0.
    >        At the next position you'd have 'b'-'a' == 1, and you'd set
    >        delta = delta * 26 + 1 == 1.  In the third position you'd get
    >        'c'-'a' == 2, delta = delta * 26 + 2 == 28.  Since the strings
    >        are now exhausted, that's your final answer.
    >
    >      2) Method (1) has a flaw, because it assumes 'b'-'a' == 'c'-'b'
    >         == ... == 'z'-'y' == 1.  This is a very common scheme for
    >         encoding letter values, but it is not universal.  You could
    >         salvage the method by looking up each character in a separate
    >         string "abcdefghijklmnopqrstuvwxyz" and subtracting their
    >         positions rather than their code values.  The strchr() function
    >         could be your friend here, and there are other possibilities too.
    >
    >      3) If the strings are of unequal length, you could pretend that the
    >         shorter had a prefix of "aaa...aaa" to extend it to the length
    >         of the longer.  In this case it might be easier to work from
    >         right to left and accumulate delta a little differently.


    Bear with this. I have enough alcohol in my system right now that if I
    would get pulled over for a DUI, the thingy the California cops use to
    test how much alcohol is on your breathe would probably be three times
    the legal limit. With that, what strategies would you use to attack
    case 3?

    Uhh... cause like, here is what I came up with so far....

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    char calculate(char first[], char second[])
    {
    char delta = 0;
    char difference = 0;

    for( ;*first && *second; *first++,*second++) {
    difference = *first - *second;
    delta = delta * 26 + difference;
    }

    return delta;
    }

    int main(void)
    {
    char first[BUFSIZ];
    char second[BUFSIZ];

    printf("Enter the first string: ");
    scanf("%s", first);
    fflush(stdout);
    printf("Enter the second string: ");
    scanf("%s", second);
    fflush(stdout);

    printf("The difference between %s - %s is %d\n", first, second, \
    calculate(first, second));

    return 0;
    }
    [cdalten@localhost oakland]$ gcc -Wall -Wextra subtractstring.c -o
    subtractstring
    subtractstring.c: In function ‘calculate’:
    subtractstring.c:10: warning: value computed is not used
    subtractstring.c:10: warning: value computed is not used
    [cdalten@localhost oakland]$ ./subtractstring
    Enter the first string: aaa
    Enter the second string: aaa
    The difference between aaa - aaa is 0
    [cdalten@localhost oakland]$ ./subtractstring
    Enter the first string: aad
    Enter the second string: aaa
    The difference between aad - aaa is 3
    [cdalten@localhost oakland]$ ./subtractstring
    Enter the first string: abc
    Enter the second string: aaa
    The difference between abc - aaa is 28
    [cdalten@localhost oakland]$

    Yes, I could have automated the test. But like, ya know, this is
    comp.lang.c. And like the standard doesn't cover such things.

    Chad
     
    Chad, Oct 26, 2010
    #10
  11. Chad <> writes:

    > On Oct 23, 2:19 pm, Eric Sosman <> wrote:
    >> On 10/23/2010 4:51 PM, John Green wrote:

    <snip>
    >> > I would like to calculate the value between two strings.  For example:
    >> > abc-aaa would be 29.

    <snip>
    >>      3) If the strings are of unequal length, you could pretend that the
    >>         shorter had a prefix of "aaa...aaa" to extend it to the length
    >>         of the longer.  In this case it might be easier to work from
    >>         right to left and accumulate delta a little differently.

    >
    > Bear with this. I have enough alcohol in my system right now that if I
    > would get pulled over for a DUI, the thingy the California cops use to
    > test how much alcohol is on your breathe would probably be three times
    > the legal limit.


    http://xkcd.com/323/

    > With that, what strategies would you use to attack
    > case 3?
    >
    > Uhh... cause like, here is what I came up with so far....
    >
    > #include <stdio.h>
    > #include <stdlib.h>
    > #include <string.h>
    >
    > char calculate(char first[], char second[])
    > {
    > char delta = 0;


    This is unlikely to be big enough.

    > char difference = 0;
    >
    > for( ;*first && *second; *first++,*second++) {


    The *s in the third clause are not doing any good.

    > difference = *first - *second;
    > delta = delta * 26 + difference;
    > }
    >
    > return delta;
    > }


    But the main point is that the above seems to have nothing much to do
    with "case 3" where the strings are of different lengths.

    <snip>
    --
    Ben.
     
    Ben Bacarisse, Oct 26, 2010
    #11
  12. On Mon, 25 Oct 2010 17:50:29 -0700 (PDT), Chad <>
    wrote:

    snip

    >
    >Uhh... cause like, here is what I came up with so far....
    >
    >#include <stdio.h>
    >#include <stdlib.h>
    >#include <string.h>
    >
    >char calculate(char first[], char second[])


    Do you really expect the calculated value to fit in a char?

    >{
    > char delta = 0;
    > char difference = 0;
    >
    > for( ;*first && *second; *first++,*second++) {


    *first++ is equivalent to *(first++). What purpose do you think the *
    serves?

    > difference = *first - *second;
    > delta = delta * 26 + difference;
    > }
    >
    > return delta;
    >}
    >
    >int main(void)
    >{
    > char first[BUFSIZ];
    > char second[BUFSIZ];
    >
    > printf("Enter the first string: ");
    > scanf("%s", first);
    > fflush(stdout);


    This is one statement too late.

    > printf("Enter the second string: ");
    > scanf("%s", second);
    > fflush(stdout);
    >
    > printf("The difference between %s - %s is %d\n", first, second, \
    > calculate(first, second));
    >
    > return 0;
    >}


    --
    Remove del for email
     
    Barry Schwarz, Oct 26, 2010
    #12
  13. John Green

    Chad Guest

    On Oct 25, 6:37 pm, Barry Schwarz <> wrote:
    > On Mon, 25 Oct 2010 17:50:29 -0700 (PDT), Chad <>
    > wrote:
    >
    > snip
    >
    >
    >
    > >Uhh... cause like, here is what I came up with so far....

    >
    > >#include <stdio.h>
    > >#include <stdlib.h>
    > >#include <string.h>

    >
    > >char calculate(char first[], char second[])

    >
    > Do you really expect the calculated value to fit in a char?
    >
    > >{
    > >  char delta = 0;
    > >  char difference = 0;

    >
    > >  for( ;*first && *second; *first++,*second++) {

    >
    > *first++ is equivalent to *(first++).  What purpose do you think the *
    > serves?


    To get what first (and second) is pointing at?

    If I redo the for statement as

    for( ;*first && *second; first++,second++) {
    difference = *first - *second;
    delta = delta * 26 + difference;
    }

    The warnings go away. I tried to think about it. But quite frankly, I
    have so much alcohol in my system right now that I have enough issue
    typing. I mean, can you only imagine what would happen if I would stop
    and think about why the latter construction actually doesn't produce
    any warnings?!
    >
    > >    difference = *first - *second;
    > >    delta  = delta * 26 + difference;
    > >  }

    >
    > >  return delta;
    > >}

    >
    > >int main(void)
    > >{
    > >  char first[BUFSIZ];
    > >  char second[BUFSIZ];

    >
    > >  printf("Enter the first string: ");
    > >  scanf("%s", first);
    > >  fflush(stdout);

    >
    > This is one statement too late.



    Does the order matter in this case?

    Chad
     
    Chad, Oct 26, 2010
    #13
  14. John Green

    Chad Guest

    On Oct 25, 6:37 pm, Ben Bacarisse <> wrote:
    > Chad <> writes:
    > > On Oct 23, 2:19 pm, Eric Sosman <> wrote:
    > >> On 10/23/2010 4:51 PM, John Green wrote:

    > <snip>
    > >> > I would like to calculate the value between two strings.  For example:
    > >> > abc-aaa would be 29.

    > <snip>
    > >>      3) If the strings are of unequal length, you could pretend that the
    > >>         shorter had a prefix of "aaa...aaa" to extend it to the length
    > >>         of the longer.  In this case it might be easier to work from
    > >>         right to left and accumulate delta a little differently.

    >
    > > Bear with this. I have enough alcohol in my system right now that if I
    > > would get pulled over for a DUI, the thingy the California cops use to
    > > test how much alcohol is on your breathe would probably be three times
    > > the legal limit.

    >
    > http://xkcd.com/323/
    >
    > > With that, what strategies would you use to attack
    > > case 3?

    >
    > > Uhh... cause like, here is what I came up with so far....

    >
    > > #include <stdio.h>
    > > #include <stdlib.h>
    > > #include <string.h>

    >
    > > char calculate(char first[], char second[])
    > > {
    > >   char delta = 0;

    >
    > This is unlikely to be big enough.
    >
    > >   char difference = 0;

    >
    > >   for( ;*first && *second; *first++,*second++) {

    >
    > The *s in the third clause are not doing any good.
    >
    > >     difference = *first - *second;
    > >     delta  = delta * 26 + difference;
    > >   }

    >
    > >   return delta;
    > > }

    >
    > But the main point is that the above seems to have nothing much to do
    > with "case 3" where the strings are of different lengths.
    >


    I was doing case 1. Then, right as I finished case 1, I realized that
    I had no idea on how to attack case 3. So instead, I posted my
    attempted solution at case one. Now I would like to point out that I
    should get a passing grade since..

    a)I was under the influence at the time I wrote this code. Wait, I
    still am.
    b)I crank this code out in less than 30 minutes. And this was done
    without the aid of google.
    c)I don't work as a computer programmer for a living.
     
    Chad, Oct 26, 2010
    #14
  15. On Mon, 25 Oct 2010 18:55:06 -0700 (PDT), Chad <>
    wrote:

    >On Oct 25, 6:37 pm, Barry Schwarz <> wrote:
    >> On Mon, 25 Oct 2010 17:50:29 -0700 (PDT), Chad <>
    >> wrote:
    >>
    >> snip
    >>
    >>
    >>
    >> >Uhh... cause like, here is what I came up with so far....

    >>
    >> >#include <stdio.h>
    >> >#include <stdlib.h>
    >> >#include <string.h>

    >>
    >> >char calculate(char first[], char second[])

    >>
    >> Do you really expect the calculated value to fit in a char?
    >>
    >> >{
    >> >  char delta = 0;
    >> >  char difference = 0;

    >>
    >> >  for( ;*first && *second; *first++,*second++) {

    >>
    >> *first++ is equivalent to *(first++).  What purpose do you think the *
    >> serves?

    >
    >To get what first (and second) is pointing at?


    But you never use the dereferenced value. That is what the diagnostic
    from your compiler was trying to tell you. The only useful effect of
    these two expressions is the side effect of increasing the pointers.

    >
    >If I redo the for statement as
    >
    >for( ;*first && *second; first++,second++) {
    > difference = *first - *second;
    > delta = delta * 26 + difference;
    >}
    >
    >The warnings go away. I tried to think about it. But quite frankly, I
    >have so much alcohol in my system right now that I have enough issue
    >typing. I mean, can you only imagine what would happen if I would stop
    >and think about why the latter construction actually doesn't produce
    >any warnings?!


    What you are saying is your opinions are irrelevant. This discussion
    is for the benefit of the OP who might otherwise be tempted to follow
    your example.

    >>
    >> >    difference = *first - *second;
    >> >    delta  = delta * 26 + difference;
    >> >  }

    >>
    >> >  return delta;
    >> >}

    >>
    >> >int main(void)
    >> >{
    >> >  char first[BUFSIZ];
    >> >  char second[BUFSIZ];

    >>
    >> >  printf("Enter the first string: ");
    >> >  scanf("%s", first);
    >> >  fflush(stdout);

    >>
    >> This is one statement too late.

    >
    >
    >Does the order matter in this case?


    Of course it does. On some systems, your printf output will not be
    visible until the fflush executes. On those systems, your user will
    not know why the system has stopped.

    --
    Remove del for email
     
    Barry Schwarz, Oct 26, 2010
    #15
  16. John Green

    Chad Guest

    > Of course it does.  On some systems, your printf output will not be
    > visible until the fflush executes.  On those systems, your user will
    > not know why the system has stopped.
    >
    > --
    > Remove del for email


    I don't know if the OP is still reading this, but how about something
    like the following (for case 1)

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    void calculate(char *value, char first[], char second[])
    {
    char difference = 0;
    char delta = 0;

    for( ;*first && *second; first++,second++) {
    difference = *first - *second;
    delta = delta * 26 + difference;
    }
    *value = delta;
    }

    int main(void)
    {
    char first[BUFSIZ];
    char second[BUFSIZ];
    size_t f_len, s_len;
    char value;

    printf("Enter the first string: ");
    fflush(stdout);
    if (scanf("%s", first) == 1) {
    f_len = strlen(first) + 1;
    } else {
    fprintf(stderr, "Try again\n");
    }

    printf("Enter the second string: ");
    fflush(stdout);
    if (scanf("%s", second) == 1) {
    s_len = strlen(second) + 1;
    } else {
    fprintf(stderr, "Try again\n");
    }

    if (f_len == s_len) {
    calculate(&value, first, second);
    printf("The difference between %s - %s is %d\n", first, second,
    value);
    } else {
    fprintf(stderr, "Lengths don't match\n");
    }

    return 0;
    }
     
    Chad, Oct 26, 2010
    #16
  17. Chad <> writes:
    >> Of course it does.  On some systems, your printf output will not be
    >> visible until the fflush executes.  On those systems, your user will
    >> not know why the system has stopped.

    >
    > I don't know if the OP is still reading this, but how about something
    > like the following (for case 1)
    >
    > #include <stdio.h>
    > #include <stdlib.h>
    > #include <string.h>
    >
    > void calculate(char *value, char first[], char second[])
    > {
    > char difference = 0;
    > char delta = 0;
    >
    > for( ;*first && *second; first++,second++) {
    > difference = *first - *second;
    > delta = delta * 26 + difference;
    > }
    > *value = delta;
    > }


    Wouldn't it be more convenient to have the function return the result
    rather than assigning it via a pointer parameter?

    The OP never bothered to tell us what "difference" means. Actually, he
    didn't even use the word "difference"; he said "the value between two
    strings".

    > int main(void)
    > {
    > char first[BUFSIZ];
    > char second[BUFSIZ];


    Why would BUFSIZ (the size of the buffer used by the setbuf function)
    be a reasonable size for an array used for interactive input? (It's
    8192 on my system.)

    > size_t f_len, s_len;
    > char value;
    >
    > printf("Enter the first string: ");
    > fflush(stdout);
    > if (scanf("%s", first) == 1) {
    > f_len = strlen(first) + 1;
    > } else {
    > fprintf(stderr, "Try again\n");
    > }


    scanf() with a "%s" format is as dangerous as gets(). It's also odd
    to ask for a string, but then read a whitespace-delimited word.

    > printf("Enter the second string: ");
    > fflush(stdout);
    > if (scanf("%s", second) == 1) {
    > s_len = strlen(second) + 1;
    > } else {
    > fprintf(stderr, "Try again\n");
    > }
    >
    > if (f_len == s_len) {


    The only thing you do with f_len and s_len is compare them here.
    You *could* just write
    if (strlen(first) == strlen(second) ...

    That's not to say that storing the lengths in variables is a bad thing
    -- but why did you add 1 to them?

    > calculate(&value, first, second);
    > printf("The difference between %s - %s is %d\n", first, second,
    > value);
    > } else {
    > fprintf(stderr, "Lengths don't match\n");
    > }
    >
    > return 0;
    > }


    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Oct 27, 2010
    #17
  18. John Green

    Chad Guest

    On Oct 26, 7:08 pm, Keith Thompson <> wrote:
    > Chad <> writes:
    > >> Of course it does.  On some systems, your printf output will not be
    > >> visible until the fflush executes.  On those systems, your user will
    > >> not know why the system has stopped.

    >
    > > I don't know if the OP is still reading this, but how about something
    > > like the following (for case 1)

    >
    > > #include <stdio.h>
    > > #include <stdlib.h>
    > > #include <string.h>

    >
    > > void calculate(char *value, char first[], char second[])
    > > {
    > >   char difference = 0;
    > >   char delta = 0;

    >
    > >   for( ;*first && *second; first++,second++) {
    > >     difference = *first - *second;
    > >     delta  = delta * 26 + difference;
    > >   }
    > >   *value = delta;
    > > }

    >
    > Wouldn't it be more convenient to have the function return the result
    > rather than assigning it via a pointer parameter?
    >


    A lot of the engineers at Lawrence Berkeley National Laboratory use
    this method. I guess in my case, it's monkey see, monkey do. I don't
    know if there is a formal computer science name to this technique or
    if this is just some kind of strange Berkeley thing.

    > The OP never bothered to tell us what "difference" means.  Actually, he
    > didn't even use the word "difference"; he said "the value between two
    > strings".
    >
    > > int main(void)
    > > {
    > >   char first[BUFSIZ];
    > >   char second[BUFSIZ];

    >
    > Why would BUFSIZ (the size of the buffer used by the setbuf function)
    > be a reasonable size for an array used for interactive input?  (It's
    > 8192 on my system.)
    >


    I was drunk at the time at wrote the original code. It was really
    hurting to think about anything at the time. So instead of trying to
    think about a reasonable buffer size, I just used BUFSIZ.

    > >   size_t f_len, s_len;
    > >   char value;

    >
    > >   printf("Enter the first string: ");
    > >   fflush(stdout);
    > >   if (scanf("%s", first) == 1) {
    > >     f_len = strlen(first) + 1;
    > >   } else {
    > >     fprintf(stderr, "Try again\n");
    > >   }

    >
    > scanf() with a "%s" format is as dangerous as gets().  It's also odd
    > to ask for a string, but then read a whitespace-delimited word.
    >


    It was the first thing that popped into my head while I was under the
    influence. In retrospect, would fgets() have been better?

    > >   printf("Enter the second string: ");
    > >   fflush(stdout);
    > >   if (scanf("%s", second) == 1) {
    > >     s_len = strlen(second) + 1;
    > >   } else {
    > >     fprintf(stderr, "Try again\n");
    > >   }

    >
    > >   if (f_len == s_len) {

    >
    > The only thing you do with f_len and s_len is compare them here.
    > You *could* just write
    >     if (strlen(first) == strlen(second) ...
    >
    > That's not to say that storing the lengths in variables is a bad thing
    > -- but why did you add 1 to them?


    I was starting to do case three[1], but then I quit because my mom was
    calling me. When I got back to my computer, I totally lost my mojo to
    write code.

    [1]Case three is what Eric talked about. And I quote

    "3) If the strings are of unequal length, you could pretend that the
    shorter had a prefix of "aaa...aaa" to extend it to the length
    of the longer. In this case it might be easier to work from
    right to left and accumulate delta a little differently. "

    Chad
     
    Chad, Oct 27, 2010
    #18
  19. Chad <> writes:

    > On Oct 26, 7:08 pm, Keith Thompson <> wrote:
    >> Chad <> writes:
    >> >> Of course it does.  On some systems, your printf output will not be
    >> >> visible until the fflush executes.  On those systems, your user will
    >> >> not know why the system has stopped.

    >>
    >> > I don't know if the OP is still reading this, but how about something
    >> > like the following (for case 1)

    >>
    >> > #include <stdio.h>
    >> > #include <stdlib.h>
    >> > #include <string.h>

    >>
    >> > void calculate(char *value, char first[], char second[])
    >> > {
    >> >   char difference = 0;
    >> >   char delta = 0;

    >>
    >> >   for( ;*first && *second; first++,second++) {
    >> >     difference = *first - *second;
    >> >     delta  = delta * 26 + difference;
    >> >   }
    >> >   *value = delta;
    >> > }


    You are still returning a char. That unlikely to be able to represent
    the result for everything but a few pairs of string.

    >> Wouldn't it be more convenient to have the function return the result
    >> rather than assigning it via a pointer parameter?

    >
    > A lot of the engineers at Lawrence Berkeley National Laboratory use
    > this method. I guess in my case, it's monkey see, monkey do. I don't
    > know if there is a formal computer science name to this technique or
    > if this is just some kind of strange Berkeley thing.


    It's worth thinking about Keith's question. Another way to think about
    the same thing is this: what *would* make you write a function that
    returns the result rather than using a pointer parameter? If the answer
    is "nothing", why do programming languages have value-returning
    functions at all? If you *can* think of reasons to return a value, why
    do they not apply in this case?

    If you can't say *why* the good folks at LBL write their programs the
    way they do, you can't draw any lessons from their code. Learning by
    copying code you don't understand is slow and error prone.

    <snip>
    --
    Ben.
     
    Ben Bacarisse, Oct 27, 2010
    #19
  20. Chad <> writes:
    > On Oct 26, 7:08 pm, Keith Thompson <> wrote:
    >> Chad <> writes:

    [...]
    >> > void calculate(char *value, char first[], char second[])
    >> > {
    >> >   char difference = 0;
    >> >   char delta = 0;

    >>
    >> >   for( ;*first && *second; first++,second++) {
    >> >     difference = *first - *second;
    >> >     delta  = delta * 26 + difference;
    >> >   }
    >> >   *value = delta;
    >> > }

    >>
    >> Wouldn't it be more convenient to have the function return the result
    >> rather than assigning it via a pointer parameter?

    >
    > A lot of the engineers at Lawrence Berkeley National Laboratory use
    > this method. I guess in my case, it's monkey see, monkey do. I don't
    > know if there is a formal computer science name to this technique or
    > if this is just some kind of strange Berkeley thing.


    A common style is to have functions return a result that indicates
    whether they succeeded or not, which means that the actual result has to
    be communicated via a pointer argument. For example, a square root
    function in this style might look something like this:

    int square_root(double *result, double x) {
    if (x < 0.0) {
    return BAD_ARGUMENT;
    }
    else {
    *result = sqrt(x);
    return OK;
    }
    }

    My guess is that that's what's going on at LBNL, and you've
    misunderstood it (it doesn't make much sense for a void function to be
    written this way).

    [...]

    >> Why would BUFSIZ (the size of the buffer used by the setbuf function)
    >> be a reasonable size for an array used for interactive input?  (It's
    >> 8192 on my system.)

    >
    > I was drunk at the time at wrote the original code.


    Ok, I give up.

    If you're not able to write coherent code (or English), you always
    have the option of *not writing anything*.

    [...]

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Oct 27, 2010
    #20
    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. AAJ
    Replies:
    0
    Views:
    642
  2. Tom
    Replies:
    6
    Views:
    598
    Diego Martins
    Mar 16, 2006
  3. nukeymusic
    Replies:
    10
    Views:
    565
    nukeymusic
    Dec 18, 2011
  4. chrismo
    Replies:
    2
    Views:
    200
    Phrogz
    Jan 16, 2007
  5. Luca Villa
    Replies:
    2
    Views:
    159
    Luca Villa
    Nov 11, 2007
Loading...

Share This Page