[comp.lang.c] C arrays of strings

richw@rosevax.Rosemount.COM (Rich Wagenknecht) (11/17/87)

Could someone explain the following declaration in english and
give an example of how to use it? I believe I can use this declaration
but cannot explain how is works. What I'm after is simply an array of
character strings.

  char *str[X.hs.

carroll@snail.UUCP (11/18/87)

	That will give you an array of 12 pointers to character. That is,
twelve pieces of memory capable of holding the address of a string. Actually
having them point at strings is a different matter. If you are going to be
doing it dynamically, you can use malloc() to get space, or you can do things
like
str[3] = "this is a string";	/* compiler allocates space */
Remember that if you use the "" notation, that the compiler allocates the space
for the string, and then makes your variable point at it, it doesn't make
another copy of it.

throopw@xyzzy.UUCP (11/18/87)

> richw@rosevax.Rosemount.COM (Rich Wagenknecht)
> Could someone explain the following declaration in english and
> give an example of how to use it? 

"No problem!"                   --- Alf

> What I'm after is simply an array of character strings.
> 
>   char *str[12];

Well, what you've got here is an array of twelve pointers to characters.
C, of course, has no "character string type" other than by convention,
so this may or may not be what you want.  In particular, the variable
"str" contains space to store twelve addresses, but does *NOT* contain
space to store any characters whatsoever.

By convention, C stores "character strings" as '\0'-terminated arrays of
characters.  Further, arrays of characters may often be represented by the
address of the first element.  Thus, if you have twelve (or fewer)
character strings existing independently of the variable "str", and wish
to keep track of them, and refer to them by expressions such as
(str[n]), then the above declaration is the right one to use.

If, on the other hand, you wish to arrange for storage space for some
characters organized as twelve strings, you must either allocate the
space explicitly if you use the above declaration, or you must declare
the space for the characters as part of "str", like so:

        char str[12][MAX_LEN];

This is an array of twelve arrays of MAX_LEN characters, which can be
viewed as an array of twelve strings of at most (MAX_LEN-1) characters.

--
"When The Cow MOOS... udders TREMBLE!"
        --- The Cow, speaking to Madame Marsupial
            (from The New Adventures of Mighty Mouse)
-- 
Wayne Throop      <the-known-world>!mcnc!rti!xyzzy!throopw

jrb@petro.UUCP (Jon Boede) (11/18/87)

I'm probably one of about 50 zillion people who are going to respond to this,
but I rolled my 20-sided die and it came up 6 ;-)

In article <3157@rosevax.Rosemount.COM> richw@rosevax.Rosemount.COM (Rich Wagenknecht) writes:
>Could someone explain the following declaration in english and
>give an example of how to use it? I believe I can use this declaration
>but cannot explain how is works. What I'm after is simply an array of
>character strings.
>
>  char *str[12];

"Str is an array of twelve pointers to characters, effectively an array of
a dozen strings."

You can use str as a "char *str" but with an index.  For example, you could
initialize it with the months of the year...

	int the_month;
	static char *str[12] = { "January", "February", ... };

	printf("It's the month of %s\n",str[the_month]);

Jon
-- 
Jon Boede	...!{gatech,ihnp4,ssbn,swrinde,tness1,utanes}!petro!jrb
512/599-1847                           2555 N.E. Loop 410, #1403, 78217
	"People who are incapable of making decisions are
	 the ones who hit those barrels at freeway exits."

jhritz@cfpas.UUCP (John Hritz) (11/18/87)

In article <3157@rosevax.Rosemount.COM> richw@rosevax.UUCP writes:
>Could someone explain the following declaration in english and
>give an example of how to use it? I believe I can use this declaration
>but cannot explain how is works. What I'm after is simply an array of
>character strings.
>
>  char *str[12];

Although it is not fool proof, a useful method for converting C declarations
to English is to use the outside/inside rule, using the type and variable
names as your boundaries. Using your example, char *str[12] would be
translated to "str is an array of 12 pointers to characters". Using one
of favorite examples in K and R, this construct could be used to store
a list of months.  Each month is variable length, you have only a pointer to
where the characters are stored.  Like so,

static char *str[] =
	{
	"January",
	"February",
	"March",
	"April",
	"May",
	"June",
	"July",
	"August",
	"September",
	"October",
	"November",
	"December"
	};
Note that in the absence of a declared size of the array, the compiler will
calculate the number of elements, in this case 12.

This contrasts with declaring the length of each of the elements which looks
similar. Ex.
static char str[][80] =
	{
	"January",
	"February",
	"March",
	"April",
	"May",
	"June",
	"July",
	"August",
	"September",
	"October",
	"November",
	"December"
	};
This will calculate the number of initializers but then allocate 80 characters
for each line.  Its not useful in this example, but its often done to 
initialize strings with default values and  allow the user of the
application to alter their contents with entries up to 80 characters long.


So, to create an array of strings, the declaration would be something like
char str[10][80] or in english "an array of 10 strings each 80 characters in
length.

For more information on creating and reading C type declarations refer to
The C Programming Language, Kerninghan and Ritchie, pp 194-195.
-- 
UUCP: ihnp4!mibte!cfpas!jhritz (John Hritz)  "Do photons have mass?...
VOICE: 313-351-3485                               Are any of them Catholic?"

chet@mandrill.UUCP (11/19/87)

In the referenced article richw@rosevax.Rosemount.COM (Rich Wagenknecht) writes:
>Could someone explain the following declaration in english and
>give an example of how to use it? I believe I can use this declaration
>but cannot explain how is works. What I'm after is simply an array of
>character strings.
>
>  char *str[12];

Script started on Wed Nov 18 20:55:31 1987

chet%cdecl
explain char *str[12]
declare str as array 12 of pointer to char

script done on Wed Nov 18 20:56:16 1987

That will do the job, if what you want is an array of character strings.

In a mailer I wrote (truly a small thing, but you have to start somewhere),
I used just such a structure to keep around the resolved addresses, after
I plucked the unresolved ones out of argv.  I also used them to point into
a large, statically-allocated array of chars (keep all the addresses in this
long array, and keep pointers to them -- you get the idea).

Chet Ramey    chet@mandrill.CWRU.Edu    {cbosgd,decvax,sun}!mandrill!chet

I think that all right-thinking people in this country are sick and
tired of being told that ordinary decent people are fed up in this
country with being sick and tired.  I'm certainly not.  But I'm
sick and tired of being told that I am.
					Monty Python 

eichin@athena.mit.edu.UUCP (11/20/87)

Another useful tool for understanding C declarations is ``cdecl''
which I found in one of project Athena's unsupported software
libraries; I believe it is public domain, but I didn't see any
comments AT ALL explaining how it works or who wrote it. Here is the
help line and a demo:

>help
        [] means optional; {} means 1 or more; <> means defined elsewhere
        command:
          declare <name> as <english>
          cast <name> into <english>
          explain <gibberish>
        english:
          function [( <name> )] returning <english>
          array [<number>] of <english>
          pointer to <english>
          <type>
        type:
          [{<modifier>}] <C-type>
          {<modifier>} [<C-type>]
          <sue> <name>
        name is a C identifier
        gibberish is a C declaration
        C-type is int, char, double or float
        modifier is short, long or unsigned
        sue is struct, union or enum
>explain char *str[12]
declare str as array 12 of pointer to char

(Note that the > chars are my addition, this program does NOT prompt).
Not great, but when you get to several levels of structures and
pointers thereto, it can help unravel things a little.

			Mark Eichin
			<eichin@athena.mit.edu>

Disclaimer: I read news to avoid playing larn. Maybe I should go back
to playing larn.

sdejarne@polyslo.UUCP (Steve DeJarnett) (11/24/87)

In article <3157@rosevax.Rosemount.COM> richw@rosevax.Rosemount.COM (Rich Wagenknecht) writes:
>Could someone explain the following declaration in english and
>give an example of how to use it? I believe I can use this declaration
>but cannot explain how is works. What I'm after is simply an array of
>character strings.
>
>  char *str[12];

	This declaration gives you an array (12 members) of pointers-to-char.
There is no storage reserved for the character strings, only 32-bits (in most
cases) to hold the address of a character string.  This declaration is just
like the char *argv[] that you get from the command line of your program.  To
get space for the character strings, you would need to do something like:

	str[1] = (char *) malloc(100);     <--- gets you space for 100 chars.

Note:  both sides of the = sign have to represent the same thing (i.e. you 
don't want to go assigning an integer to a character (usually :-)).  To make
sure you have the right thing on both sides, cover up the part in the
declaration that you have in your equation:  In this case cover up the str[12]
in the declaration and the str[1] in the equation.  Whatever is left over on
the declaration line is what you have (in this case, a char pointer).  I hope
that made sense, but if not, ignore it.  

	Here is some code that uses char *str[12].


void func()
{
    char *str[12];
    char *malloc();
    int i;
    
    for (i=0;i<=12;i++)
      {
	str[i] = malloc(80);
	printf("enter a string> ");
	gets(str[i]);
      }

    for (i=0;i<=12;i++)
	printf(String %d = %s\n",i,str[i]);
    return;
}

	Hope this helps.


-------------------------------------------------------------------------------
| Steve DeJarnett		|    ...!ihnp4!csun!polyslo!sdejarne	      |
| Computer Systems Lab		|    ...!{csustan,csun,sdsu}!polyslo!sdejarne |
| Cal Poly State Univ		|    ...!ucbvax!voder!polyslo!sdejarne	      |
| San Luis Obispo, CA  93407	|    					      |
-------------------------------------------------------------------------------
#include <std_disclaimer.h>

eichin@athena.mit.edu (Mark W. Eichin) (12/01/87)

I have received a small number of requests for cdecl (not enough to
warrant posting it in its entirety; it is a 14K shar file.) However, I
have since determined that it is in

		comp.source.unix/volume6/cdecl 

If Jan Vandenbos is reading this: you should try to get it from a
comp.sources.unix archive (like UUNET.UU.NET if you can reach it), or
send me a better path (one that does not go through UNCAEDU, at any
rate).
				Mark Eichin	
				<eichin@athena.mit.edu>