# calculate value between two strings

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

1. ### John GreenGuest

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

2. ### Ian CollinsGuest

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

3. ### Eric SosmanGuest

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

> 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

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
4. ### Keith ThompsonGuest

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.

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
5. ### EyegorGuest

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.
>
>
> --
> 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
6. ### EyegorGuest

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.

>

>
> > --
> > 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
7. ### Keith ThompsonGuest

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
8. ### Ben BacarisseGuest

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.

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
9. ### Barry SchwarzGuest

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?

>}
>

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

--
Remove del for email

Barry Schwarz, Oct 24, 2010

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
>
> > 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
>
>      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 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.

11. ### Ben BacarisseGuest

> 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
12. ### Barry SchwarzGuest

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

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?

On Oct 25, 6:37 pm, Ben Bacarisse <> wrote:
> > 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
c)I don't work as a computer programmer for a living.

15. ### Barry SchwarzGuest

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

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

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

17. ### Keith ThompsonGuest

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

> 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

On Oct 26, 7:08 pm, Keith Thompson <> wrote:
> >> 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. "

19. ### Ben BacarisseGuest

> On Oct 26, 7:08Â pm, Keith Thompson <> wrote:
>> >> 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.

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
20. ### Keith ThompsonGuest

> On Oct 26, 7:08Â pm, Keith Thompson <> wrote:

[...]
>> > 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) {
}
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