Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to passing multidimesional array of string to function?

89 views
Skip to first unread message

Alter

unread,
Jul 23, 2012, 7:53:29 AM7/23/12
to


Hi all


How to pass a multidimensional array of string to a function?



Thanks in advance

Cheers






Eric Sosman

unread,
Jul 23, 2012, 8:54:04 AM7/23/12
to
On 7/23/2012 7:53 AM, Alter wrote:
> Hi all
>
>
> How to pass a multidimensional array of string to a function?

This might be Question 6.19 on the comp.lang.c Frequently
Asked Questions (FAQ) page at <http://www.c-faq.com/>. Or it
might be 6.18, or 6.20, or -- Tell you what: Read Section 6 of
the FAQ, and post again with more detail if things still aren't
clear.


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

Ben Bacarisse

unread,
Jul 23, 2012, 9:07:43 AM7/23/12
to
"Alter" <n...@alt.invalid> writes:

> How to pass a multidimensional array of string to a function?

That's not a very good question. It has a literal answer that you
probably did not mean (you pass it like any other array), and the phase
"multidimensional array of string[s]" has all sorts of possible
meanings.

What have you tried so far? Do you have an example you can show?

--
Ben.

Malcolm McLean

unread,
Jul 23, 2012, 11:05:05 AM7/23/12
to
בתאריך יום שני, 23 ביולי 2012 12:53:29 UTC+1, מאת Alter:
> Hi all
>
>
> How to pass a multidimensional array of string to a function?
>
>
>
void multidstringfunction(char **str, int *dims, int Ndims)
{
int i;
int width = 1;

/* let's print the strings along the major dimension */
assert(Ndims > 1);
/* we don't know how many other dimensions there are, so we've got to
work out the block width */
for(i=1;i<Ndims;i++)
width *= dims[i];

/* now we can get the string at [i, 0, 0, 0 ...] by multiplying
by width */
for(i=0;i<dims[0];i++)
printf("string %d - %s\n", str[i*width];
}

pete

unread,
Jul 23, 2012, 10:51:14 PM7/23/12
to
/* BEGIN new.c */

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

#define SORT_FUNCTIONS \
no_sort, "Original order of the test arrays:", \
slsort, "Nonstable simple selection sort:", \
i_sort, "Stable insertionsort:", \
qsort, "Standard library qsort;\n" \
"unspecified ordering of equal keys:"

#define NUMBERS \
"zero","one","two","three","four","five", \
"six","seven","eight","nine","ten"

#define NMEMB(A) (sizeof (A) / sizeof *(A))

int comp(const void *a, const void *b);
void no_sort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
void slsort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
void i_sort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));

int
main(void)
{
size_t element, sort;
struct sf {
void (*func)(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
const char *description;
} s_F[] = {SORT_FUNCTIONS};
const char numbers[][sizeof "three"] = {NUMBERS};
char array[NMEMB(numbers)][sizeof "three"];

puts("\n/* BEGIN output from new.c */\n\n"
"Arrays of (char [sizeof \"three\"]),\n"
"are being sorted by string length.\n");
for (sort = 0; sort != NMEMB(s_F); ++sort) {
memcpy(array, numbers, sizeof array);
s_F[sort].func(array, NMEMB(array), sizeof*array, comp);
puts(s_F[sort].description);
for (element = 0; element != NMEMB(array); ++element) {
puts(array[element]);
}
putchar('\n');
}
puts("/* END output from new.c */");
return 0;
}

int
comp(const void *a, const void *b)
{
const char (*const aaa)[sizeof "three"] = a;
const char (*const bbb)[sizeof "three"] = b;
const char *aa = *aaa;
const char *bb = *bbb;

while (*aa != '\0' && *bb != '\0') {
++aa;
++bb;
}
return *bb != '\0' ? -1 : *aa != '\0';
}

void
no_sort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *))
{
base, nmemb, size, compar;
}

void
slsort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *))
{
size_t tail;
unsigned char *array, *first, *middle, *end, swap;

if (nmemb-- > 1) {
end = base;
do {
array = end;
end += size;
first = middle = end;
tail = nmemb;
while (--tail != 0) {
middle += size;
if (compar(first, middle) > 0) {
first = middle;
}
}
if (compar(array, first) > 0) {
do {
swap = *first;
*first++ = *array;
*array++ = swap;
} while (array != end);
}
} while (--nmemb != 0);
}
}

void
i_sort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *))
{
unsigned char *array, *low, *high, *p1, *p2, swap;

if (nmemb-- > 1) {
array = base;
do {
low = array;
high = low + size;
array = high;
while (compar(low, high) > 0) {
p1 = high;
p2 = low;
do {
swap = *p1;
*p1++ = *p2;
*p2++ = swap;
} while (p2 != high);
if (low == base) {
break;
}
high = low;
low -= size;
}
} while (--nmemb != 0);
}
}

/* END new.c */

--
pete

Alter

unread,
Jul 24, 2012, 1:08:34 PM7/24/12
to


This type of array:

char *word[50][50]={{"123", "3048548t", "fd�fkd9ds8","0"," ",...},...}

As it passed to the function?


Must be written as the prototype of the function, and should be used?



Regards


Varun Tewari

unread,
Jul 24, 2012, 1:21:56 PM7/24/12
to
Eventually, its a char pointer.
If you don't have serious string operations, and only interested in reading values or other trivial operations, u can pass it merely as char * to the function.

Ben Bacarisse

unread,
Jul 24, 2012, 1:28:23 PM7/24/12
to
"Alter" <n...@alt.invalid> writes:

> This type of array:
>
> char *word[50][50]={{"123", "3048548t", "fdòfkd9ds8","0"," ",...},...}
>
> As it passed to the function?
>
>
> Must be written as the prototype of the function, and should be used?

You can write

void f(char *wa[][50]);

or you can use the slightly cryptic

void f(char *(*wa)[50]);

These are not the only ways, but they are probably the most idiomatic.

--
Ben.

Eric Sosman

unread,
Jul 24, 2012, 1:50:08 PM7/24/12
to
On 7/24/2012 1:21 PM, Varun Tewari wrote:
> Eventually, its a char pointer.

No: A "multidimensional array of string" might be any of a
few different things, but "a char pointer" is not among them.
This might be a good time to review Section 6 of the FAQ at
<http://www.c-faq.com/>.

> If you don't have serious string operations, and only interested in reading values or other trivial operations, u can pass it merely as char * to the function.

No. Section 6.

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

Ike Naar

unread,
Jul 24, 2012, 2:16:46 PM7/24/12
to
On 2012-07-24, Alter <n...@alt.invalid> wrote:
> This type of array:
>
> char *word[50][50]={{"123", "3048548t", "fd?fkd9ds8","0"," ",...},...}
>
> As it passed to the function?
>
> Must be written as the prototype of the function, and should be used?

Please read chapter 6 of the C FAQ if you haven't already done so.

Now, here's one possibility:

/* begin example0.c */

#include <string.h>
#include <assert.h>

static void check(char *word[][50], int row, int col, char const *expect)
{
assert(0 == strcmp(word[row][col], expect));
}

int main(void)
{
char *word[50][50] = {{"0:0"}, {"1:0", "1:1", "1:2"}, {"2:0", "2:1"}};
check(word, 1, 2, "1:2");
check(word, 2, 1, "2:1");
return 0;
}

/* end example0.c */


Here's another possibilty, using variable length arrays
(works with C99 or newer).
It has the advantage that you can use the function for any
two-dimensional array of strings, regardless the size.

/* begin example1.c */

#include <string.h>
#include <assert.h>

static void check(int nrows, int ncols, char *word[nrows][ncols],
int row, int col, char const *expect)
{
assert(0 == strcmp(word[row][col], expect));
}

int main(void)
{
char *word[50][50] = {{"0:0"}, {"1:0", "1:1", "1:2"}, {"2:0", "2:1"}};
check(50, 50, word, 1, 2, "1:2");
check(50, 50, word, 2, 1, "2:1");
return 0;
}

/* end example1.c */


Here's another one, that adds a level of indirection, so that
a pointer to the array is passed, instead of passing the array.
The advantage is that the compiler will verify that both dimensions
of the passed array match exactly.

/* begin example2.c */

#include <string.h>
#include <assert.h>

static void check(char *(*word)[50][50], int row, int col, char const *expect)
{
assert(0 == strcmp((*word)[row][col], expect));
}

int main(void)
{
char *word[50][50] = {{"0:0"}, {"1:0", "1:1", "1:2"}, {"2:0", "2:1"}};
check(&word, 1, 2, "1:2");
check(&word, 2, 1, "2:1");
return 0;
}

/* end example2.c */


Alter

unread,
Jul 24, 2012, 3:40:22 PM7/24/12
to


Hi


I mean as an array multidimesional, a two-dimensional array.


Cheers





Malcolm McLean

unread,
Jul 24, 2012, 4:16:42 PM7/24/12
to
בתאריך יום שלישי, 24 ביולי 2012 20:40:22 UTC+1, מאת Alter:
> Hi
>
>
> I mean as an array multidimesional, a two-dimensional array.
>
>
C doesn't have good syntax for two dimensional arrays. Its' easy enough to declare them, but to resize them , pass them about, and extract .lines and columns is difficult.
Its' best to treat your 2d arrays as 1d arrays, and do the calculation manually. array[y*width+x] will give you the element at y, x.

Fred K

unread,
Jul 24, 2012, 4:22:03 PM7/24/12
to
On Tuesday, July 24, 2012 1:16:42 PM UTC-7, Malcolm McLean wrote:
> בתאריך יום שלישי, 24 ביולי 2012 20:40:22 UTC+1, מאת Alter:
> &gt; Hi
> &gt;
> &gt;
> &gt; I mean as an array multidimesional, a two-dimensional array.
> &gt;
> &gt;
> C doesn&#39;t have good syntax for two dimensional arrays. Its&#39; easy enough to declare them, but to resize them , pass them about, and extract .lines and columns is difficult.
> Its&#39; best to treat your 2d arrays as 1d arrays, and do the calculation manually. array[y*width+x] will give you the element at y, x.

Unless the 2D array was created by creating a 1D array of pointers to 1d arrays.

Fred K

unread,
Jul 24, 2012, 4:22:39 PM7/24/12
to
On Tuesday, July 24, 2012 1:22:03 PM UTC-7, Fred K wrote:
> On Tuesday, July 24, 2012 1:16:42 PM UTC-7, Malcolm McLean wrote:
> &gt; בתאריך יום שלישי, 24 ביולי 2012 20:40:22 UTC+1, מאת Alter:
> &gt; &amp;gt; Hi
> &gt; &amp;gt;
> &gt; &amp;gt;
> &gt; &amp;gt; I mean as an array multidimesional, a two-dimensional array.
> &gt; &amp;gt;
> &gt; &amp;gt;
> &gt; C doesn&amp;#39;t have good syntax for two dimensional arrays. Its&amp;#39; easy enough to declare them, but to resize them , pass them about, and extract .lines and columns is difficult.
> &gt; Its&amp;#39; best to treat your 2d arrays as 1d arrays, and do the calculation manually. array[y*width+x] will give you the element at y, x.
>
> Unless the 2D array was created by creating a 1D array of pointers to 1d arrays.

(In which case it isn't really a 2D array)

Ben Bacarisse

unread,
Jul 24, 2012, 5:07:03 PM7/24/12
to
"Alter" <n...@alt.invalid> writes:

> I mean as an array multidimesional, a two-dimensional array.

Are the answers you've had unsuitable? If so, just repeating yourself
like this probably won't get you closer to whatever the real problem is.

--
Ben.

Ben Bacarisse

unread,
Jul 24, 2012, 5:19:19 PM7/24/12
to
Malcolm McLean <malcolm...@btinternet.com> writes:

> בתאריך יום שלישי, 24 ביולי 2012 20:40:22 UTC+1, מאת Alter:
>>
>> I mean as an array multidimesional, a two-dimensional array.
>>
> C doesn't have good syntax for two dimensional arrays.

That's not good advice to give beginners because it's such a loaded
value judgement.

To the OP: C has syntax for two dimensional arrays and you should make
your own mind up if it is "good" after you learn about it. Many people
find it perfectly adequate for many tasks. No language has perfect
arrays, ideal for all circumstances[1].

> Its' easy enough to declare them, but to resize them , pass them
> about, and extract .lines and columns is difficult. Its' best to
> treat your 2d arrays as 1d arrays, and do the calculation
> manually. array[y*width+x] will give you the element at y, x.

That's bad advice. Doing this does not simplify resizing or accessing
columns. Accessing rows is perfectly simple using both methods. What
the problem is in "passing them about" I don't know.

[1] Except Algol 68, of course. :-)

--
Ben.

Stephen Sprunk

unread,
Jul 24, 2012, 8:45:21 PM7/24/12
to
On 24-Jul-12 15:16, Malcolm McLean wrote:
> בתאריך יום שלישי, 24 ביולי 2012 20:40:22 UTC+1, מאת Alter:
>> I mean as an array multidimesional, a two-dimensional array.
>
> C doesn't have good syntax for two dimensional arrays.

C does have a syntax for multidimensional arrays; how "good" it may be
is purely in the eye of the beholder. IMHO, it does an adequate job of
doing what it's designed to do.

> Its' best to treat your 2d arrays as 1d arrays, and do the
> calculation manually. array[y*width+x] will give you the element
> at y, x.

That's all the C array subscript operator does internally anyway, so you
have thrown away the syntactic sugar and type checking for no real
advantage--and increased the opportunity for bugs.

Do you propose everyone use (*ptr).field instead of ptr->field as well?

S

--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking

aftnix

unread,
Jul 26, 2012, 4:35:12 PM7/26/12
to
what have you tried?

Barry Schwarz

unread,
Jul 27, 2012, 6:05:18 PM7/27/12
to
On Monday, July 23, 2012 6:53:29 AM UTC-5, Alter wrote:
> Hi all
>
> How to pass a multidimensional array of string to a function?

In the function prototype and in the function definition, you declare the parameter that will correspond to the array to exactly match the definition of the array itself. For example:

If your array of string is defined as char x[12][45] then your function should specify void f(char y[12][45]) and you would call the function with f(x);

If your array of string is defined as char *x[26] then your function should specify void f(char *y[26]) and you would call the function with f(x);

Later, when you understand the intricacies of how arrays are passed to functions, you can start to look at other declarations.

C3PO

unread,
Jul 28, 2012, 4:41:36 PM7/28/12
to
On Tue, 24 Jul 2012 13:50:08 -0400, Eric Sosman wrote:
> On 7/24/2012 1:21 PM, Varun Tewari wrote:
>> Eventually, its a char pointer.
>
> No: A "multidimensional array of string" might be any of a
> few different things, but "a char pointer" is not among them.

No, Varun is correct here. C pointers can be complicated so I will
explain in some detail.

First, you must understand that arrays and pointers are really the same
thing under the hood. An array is kind of like a fixed length pointer.

So "array of X" = "pointer to X", here X can be anything (except void,
where we can have a pointer to a void type but not a void array).

Now, the string type in C is char*, e.g. pointer to char. However when
people talk of "pointer to a string" they mean "pointer to a sequence of
chars terminating in the NULL byte (\000). So "pointer to string" =
"string".

Now we have:

array of string
= pointer to string
= string
= char *

Hope that helps. It took me a while to get comfortable with this stuff.

Best regards,
___ C3PO ___

Keith Thompson

unread,
Jul 28, 2012, 6:04:19 PM7/28/12
to
C3PO <nos...@nospam.com> writes:
> On Tue, 24 Jul 2012 13:50:08 -0400, Eric Sosman wrote:
>> On 7/24/2012 1:21 PM, Varun Tewari wrote:
>>> Eventually, its a char pointer.
>>
>> No: A "multidimensional array of string" might be any of a
>> few different things, but "a char pointer" is not among them.
>
> No, Varun is correct here. C pointers can be complicated so I will
> explain in some detail.
>
> First, you must understand that arrays and pointers are really the same
> thing under the hood. An array is kind of like a fixed length pointer.

This is a common misconception, and it's absolutely wrong.

As yourself this. What is the size of a pointer? (Answer: It
varies, but it's typically 4 or 8 bytes.) What is the size of
a string? (Answer: It's the length of the string, plus 1 for the
terminating '\0', generally *not* the size of a pointer.)

What does this print?

char s[] = "hello, world";
printf("sizeof (char*) = %d\n", (int)sizeof (char*));
printf("sizeof s = %d\n", (int)sizeof s);

On my system, it prints:

sizeof (char*) = 4
sizeof s = 13

How would the output make sense if arrays and pointers were "really
the same thing"?

> So "array of X" = "pointer to X", here X can be anything (except void,
> where we can have a pointer to a void type but not a void array).

No, it absolutely is not.

Read section 6 of the comp.lang.c FAQ, <http://www.c-faq.com/>.
Read it now, before you post anything more here.

> Now, the string type in C is char*, e.g. pointer to char.

There is no "string type" in C. A "string" is a data *layout*, not a
data type. A string is, by definition, "a contiguous sequence of
characters terminated by and including the first null character".

A char* value may *point* to a string. More precisely, it may point to
the first character of a string, but the standard additionally defines a
"pointer to a string" as "a pointer to its initial (lowest addressed)
character"..

> However when
> people talk of "pointer to a string" they mean "pointer to a sequence of
> chars terminating in the NULL byte (\000). So "pointer to string" =
> "string".

It's clearer to avoid using the term "NULL" to refer to a null
character. NULL is a macro, defined in the standard library, that
expands to a null *pointer* constant.

> Now we have:
>
> array of string
> = pointer to string
> = string
> = char *

Nope.

> Hope that helps. It took me a while to get comfortable with this stuff.

I'm afraid it's still going to take you a while longer.

Again, read section 6 of the comp.lang.c FAQ, <http://www.c-faq.com/>.
After that, please feel free to post again if you have any questions.

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Eric Sosman

unread,
Jul 28, 2012, 10:07:12 PM7/28/12
to
On 7/28/2012 4:41 PM, C3PO wrote:
> On Tue, 24 Jul 2012 13:50:08 -0400, Eric Sosman wrote:
>> On 7/24/2012 1:21 PM, Varun Tewari wrote:
>>> Eventually, its a char pointer.
>>
>> No: A "multidimensional array of string" might be any of a
>> few different things, but "a char pointer" is not among them.
>
> No, Varun is correct here. C pointers can be complicated so I will
> explain in some detail.
>
> First, you must understand that arrays and pointers are really the same
> thing under the hood. An array is kind of like a fixed length pointer.

If you had read (and understood) Section 6 of the FAQ,
you would have known better than to post this nonsense.

> So "array of X" = "pointer to X", here X can be anything (except void,
> where we can have a pointer to a void type but not a void array).

Wrong, both for the reasons explained in FAQ 6.* and for an
additional and altogether different reason that I don't believe
the FAQ covers. Congratulations: You have discovered an Infrequent
fallacy! (Hint: Is `void' the only incomplete type?)

> Now, the string type in C is char*, e.g. pointer to char. However when
> people talk of "pointer to a string" they mean "pointer to a sequence of
> chars terminating in the NULL byte (\000). So "pointer to string" =
> "string".
>
> Now we have:
>
> array of string
> = pointer to string
> = string
> = char *
>
> Hope that helps. It took me a while to get comfortable with this stuff.

There can be comfort in ignorance, yes. There's greater
utility, though, in curing your ignorance. Read Section 6.

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

Phil Carmody

unread,
Jul 29, 2012, 4:33:33 AM7/29/12
to
C3PO <nos...@nospam.com> writes:
> On Tue, 24 Jul 2012 13:50:08 -0400, Eric Sosman wrote:
> > On 7/24/2012 1:21 PM, Varun Tewari wrote:
> >> Eventually, its a char pointer.
> >
> > No: A "multidimensional array of string" might be any of a
> > few different things, but "a char pointer" is not among them.
>
> No, Varun is correct here. C pointers can be complicated so I will
> explain in some detail.
>
> First, you must understand that arrays and pointers are really the same
> thing under the hood. An array is kind of like a fixed length pointer.

No.

> So "array of X" = "pointer to X", here X can be anything (except void,
> where we can have a pointer to a void type but not a void array).

No.

> Now, the string type in C is char*

No.

>, e.g. pointer to char. However when
> people talk of "pointer to a string" they mean "pointer to a sequence of
> chars terminating in the NULL byte (\000). So "pointer to string" =
> "string".
>
> Now we have:
>
> array of string
> = pointer to string
> = string
> = char *

An eyes-popping-out-of-head-inducing no!

> Hope that helps. It took me a while to get comfortable with this stuff.

You are not comfortable with this stuff. You are dangerously wrong.
Please don't code any more C until you've read the relevant parts of K&R
again.

Phil
--
> I'd argue that there is much evidence for the existence of a God.
Pics or it didn't happen.
-- Tom (/. uid 822)
0 new messages