[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c

length of strings in a two dimensional array

dr.oktopus

4/19/2011 8:54:00 PM

Hello,
here I am talking about having good habits in code writing.
I have a simple problem: have two messages that represent
the same string, one in lowercase and the other in uppercase
letter. Under some circustamces, I want to print the first or
the second, so I couple them inside an array and use a
variable "allcaps" as index.
And I have to precompute the length of the strings, that are CONSTANT
strings.

A solution is:

const char *messages[2] = { "this is lowercase string", "this is
uppercase string" };

and

#define MESSAGE_LEN (strlen(messages[0])

But what if you prefer, as good habits could suggest, to rewrite
all using only arrays and the sizeof operator?

const char message_lo[] = "this is lowercase";
const char message_up[] = "this is uppercase";

#define MESSAGE_LEN (sizeof(message_lo) - 1)

const char messages[2][MESSAGE_LEN] = { &message_lo, &message_hi };

What is better? (I think the answer is: "none")
Thanks,
willy
16 Answers

Morris Keesan

4/19/2011 9:08:00 PM

0

On Tue, 19 Apr 2011 16:54:09 -0400, dr.oktopus
<blindwilly@freeonline.zzn.com> wrote:

> Hello,
> here I am talking about having good habits in code writing.
> I have a simple problem: have two messages that represent
> the same string, one in lowercase and the other in uppercase
> letter. Under some circustamces, I want to print the first or
> the second, so I couple them inside an array and use a
> variable "allcaps" as index.
> And I have to precompute the length of the strings, that are CONSTANT
> strings.
>
> A solution is:
>
> const char *messages[2] = { "this is lowercase string", "this is
> uppercase string" };
>
> and
>
> #define MESSAGE_LEN (strlen(messages[0])

Besides the missing close parenthesis: defining MESSAGE_LEN this way,
you're not precomputing the length of the strings. Every time you write
MESSAGE_LEN in your code, this will result in a call to strlen().

> But what if you prefer, as good habits could suggest, to rewrite
> all using only arrays and the sizeof operator?
>
> const char message_lo[] = "this is lowercase";
> const char message_up[] = "this is uppercase";
>
> #define MESSAGE_LEN (sizeof(message_lo) - 1)
>
> const char messages[2][MESSAGE_LEN] = { &message_lo, &message_hi };
>
> What is better? (I think the answer is: "none")

I prefer the second approach, because then MESSAGE_LEN really is a
constant, and you compute it at compile time rather than while the
program is running. If it were me, I would also put in somewhere
a line that says
assert(sizeof message_lo == sizeof message_up);


[Note how, in answering your message, I've included all of the context
that a reader of my message needs in order to understand what I'm saying,
rather than assuming that said reader is using Google groups and has easy
access to your message.]


--
Morris Keesan -- mkeesan@post.harvard.edu

Barry Schwarz

4/20/2011 1:34:00 AM

0

On Tue, 19 Apr 2011 13:54:09 -0700 (PDT), "dr.oktopus"
<blindwilly@freeonline.zzn.com> wrote:

>Hello,
>here I am talking about having good habits in code writing.
>I have a simple problem: have two messages that represent
>the same string, one in lowercase and the other in uppercase
>letter. Under some circustamces, I want to print the first or
>the second, so I couple them inside an array and use a
>variable "allcaps" as index.
>And I have to precompute the length of the strings, that are CONSTANT
>strings.
>
>A solution is:
>
>const char *messages[2] = { "this is lowercase string", "this is
>uppercase string" };
>
>and
>
>#define MESSAGE_LEN (strlen(messages[0])
>
>But what if you prefer, as good habits could suggest, to rewrite
>all using only arrays and the sizeof operator?
>
>const char message_lo[] = "this is lowercase";
>const char message_up[] = "this is uppercase";
>
>#define MESSAGE_LEN (sizeof(message_lo) - 1)
>
>const char messages[2][MESSAGE_LEN] = { &message_lo, &message_hi };

Of course this is illegal since no part of messages contains any
address. Did you perhaps mean to use #define instead of const char?

And if you do, you probably need to remove the -1 from the computation
of MESSAGE_LEN. Your stated goal is to have strings and they need the
terminating '\0'.

>
>What is better? (I think the answer is: "none")

--
Remove del for email

dr.oktopus

4/20/2011 9:09:00 AM

0

>
> >const char messages[2][MESSAGE_LEN] = { &message_lo, &message_hi };
>
> Of course this is illegal since no part of messages contains any
> address.  Did you perhaps mean to use #define instead of const char?  
>

Using something like:

#define message_lo "this is lowercase"
#define message_hi "this is uppercase"

prevents me to use the sizeof operator, so we return at the start
point.

> And if you do, you probably need to remove the -1 from the computation
> of MESSAGE_LEN.  Your stated goal is to have strings and they need the
> terminating '\0'.
>

No, really I don't need it. I use strings but output is not done via
printf or similar.

James Kuyper

4/20/2011 11:01:00 AM

0

On 04/20/2011 05:09 AM, dr.oktopus wrote:
>>
>>> const char messages[2][MESSAGE_LEN] = { &message_lo, &message_hi };
>>
>> Of course this is illegal since no part of messages contains any
>> address. �Did you perhaps mean to use #define instead of const char? �

Pay attention to the fact that this code is a constraint violation. It
doesn't matter what problems you might have with the alternative
approaches - this approach can not work, so you must choose one of the
alternatives.

> Using something like:
>
> #define message_lo "this is lowercase"
> #define message_hi "this is uppercase"
>
> prevents me to use the sizeof operator, so we return at the start
> point.

With the above #defines, nothing prevents you from using the expression
"sizeof message_lo"; the expression is an integer constant expression
which may be used for, among other things, the following uses:

#define MESSAGE_LEN (sizeof message_lo - 1)
const char messages[2][MESSAGE_LEN] =
{message_lo, message_high};

Note, among other things, the absense of the '&' operator from this
re-write.
--
James Kuyper

Ian Collins

4/20/2011 11:13:00 AM

0

On 04/20/11 11:00 PM, James Kuyper wrote:
> On 04/20/2011 05:09 AM, dr.oktopus wrote:
>>>
>>>> const char messages[2][MESSAGE_LEN] = {&message_lo,&message_hi };
>>>
>>> Of course this is illegal since no part of messages contains any
>>> address. �Did you perhaps mean to use #define instead of const char? �
>
> Pay attention to the fact that this code is a constraint violation. It
> doesn't matter what problems you might have with the alternative
> approaches - this approach can not work, so you must choose one of the
> alternatives.
>
>> Using something like:
>>
>> #define message_lo "this is lowercase"
>> #define message_hi "this is uppercase"
>>
>> prevents me to use the sizeof operator, so we return at the start
>> point.
>
> With the above #defines, nothing prevents you from using the expression
> "sizeof message_lo"; the expression is an integer constant expression
> which may be used for, among other things, the following uses:
>
> #define MESSAGE_LEN (sizeof message_lo - 1)

Did you intend to loose the trailing '\0'?

--
Ian Collins

James Kuyper

4/20/2011 11:38:00 AM

0

On 04/20/2011 07:13 AM, Ian Collins wrote:
> On 04/20/11 11:00 PM, James Kuyper wrote:
>> > On 04/20/2011 05:09 AM, dr.oktopus wrote:
....
>>> >> #define message_lo "this is lowercase"
....
>> > #define MESSAGE_LEN (sizeof message_lo - 1)
> Did you intend to loose the trailing '\0'?

Yes, since dr. oktopus has explicitly stated that he wants to lose the
trailing '\0'. He's working with fixed-length strings, rather than
null-terminated strings (NTS). That is a legitimate choice, though not a
convenient one in C. It means he can't use any of the NTS utilities in
the C standard library.
--
James Kuyper

Eric Sosman

4/20/2011 12:12:00 PM

0

On 4/19/2011 4:54 PM, dr.oktopus wrote:
> Hello,
> here I am talking about having good habits in code writing.
> I have a simple problem: have two messages that represent
> the same string, one in lowercase and the other in uppercase
> letter. Under some circustamces, I want to print the first or
> the second, so I couple them inside an array and use a
> variable "allcaps" as index.
> And I have to precompute the length of the strings, that are CONSTANT
> strings.
>
> A solution is:
>
> const char *messages[2] = { "this is lowercase string", "this is
> uppercase string" };

Ah. This is obviously some strange usage of the word "uppercase"
that I hadn't previously been aware of.

> and
>
> #define MESSAGE_LEN (strlen(messages[0])

Missing a parenthesis, and not a "CONSTANT" in any event.

> But what if you prefer, as good habits could suggest, to rewrite
> all using only arrays and the sizeof operator?
>
> const char message_lo[] = "this is lowercase";
> const char message_up[] = "this is uppercase";
>
> #define MESSAGE_LEN (sizeof(message_lo) - 1)
>
> const char messages[2][MESSAGE_LEN] = {&message_lo,&message_hi };
>
> What is better? (I think the answer is: "none")

Neither is much good, and the second won't even compile.

It's not clear why you're so worried about CONSTANTs or about
having the strings in an array, but one possibility is

#define LOWER "this is lowercase string"
#define UPPER "THIS IS CAPITALIZED STRING"
#define MESSAGE_LEN (sizeof LOWER > sizeof UPPER \
? sizeof LOWER : sizeof UPPER)
const char messages[][MESSAGE_LEN] = { LOWER, UPPER };

I don't know whether you'll find this useful, because I don't
really understand why you've adopted all these strictures, nor
what others may lurk unposted.

--
Eric Sosman
esosman@ieee-dot-org.invalid

Mel Smith

4/20/2011 3:26:00 PM

0

Hi:

I'm Mr. Butinsky here but since my language (xHarbour) is really a
slightly higher level of C, here is the xHarbour solution:

Function PrintUpperLower(nIndex)

// Here we make a 'static' array which is created at compile time
// and is only created once

STATIC aMessages := {"this is a lowercase string","THIS IS AN
UPPERCASE STRING"}

// now do your printing however you can, e.g.:
? aMessages[nIndex] // and the printing happens at the bnext
place on the screen

// or
@ 12,10 SAY aMessages[nIndex] // to print on line 12, column 10
of the screen

// or use a hardcopy printing routine available to you


RETURN NIL


-Mel Smith


dr.oktopus

4/20/2011 4:47:00 PM

0

On 20 Apr, 13:12, Eric Sosman <esos...@ieee-dot-org.invalid> wrote:
> On 4/19/2011 4:54 PM, dr.oktopus wrote:
>
> > Hello,
> > here I am talking about having good habits in code writing.
> > I have a simple problem: have two messages that represent
> > the same string, one in lowercase and the other in uppercase
> > letter. Under some circustamces, I want to print the first or
> > the second, so I couple them inside an array and use a
> > variable "allcaps" as index.
> > And I have to precompute the length of the strings, that are CONSTANT
> > strings.
>
> > A solution is:
>
> > const char *messages[2] = { "this is lowercase string", "this is
> > uppercase string" };
>
>      Ah. This is obviously some strange usage of the word "uppercase"
> that I hadn't previously been aware of.
>

a better example:

#define message_lo "the quick brown fox jumps over the lazy dog"
#define message_hi "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG"

the point is that the strings have the same length

dr.oktopus

4/20/2011 4:52:00 PM

0

>
> > Using something like:
>
> > #define message_lo "this is lowercase"
> > #define message_hi "this is uppercase"
>
> > prevents me to use the sizeof operator, so we return at the start
> > point.
>
> With the above #defines, nothing prevents you from using the expression
> "sizeof message_lo";

Is guaranteed that C will not apply that sizeof as if it would be
a sizeof(char *)?